mirror of
https://github.com/notwa/rc
synced 2024-11-05 06:29:02 -08:00
add notice
for uploading files and gotify'ing them
This commit is contained in:
parent
79e81f07d7
commit
8e36e2073f
1 changed files with 296 additions and 0 deletions
296
sh/notice
Executable file
296
sh/notice
Executable file
|
@ -0,0 +1,296 @@
|
|||
#!/usr/bin/env sh
|
||||
# YES_ZSH YES_BASH YES_DASH YES_ASH
|
||||
|
||||
__notice_warn() {
|
||||
printf 'notice: %s\n' >&2 "$*"
|
||||
}
|
||||
|
||||
__notice_curl() {
|
||||
curl -q --no-progress-meter 0.0.0.0 >/dev/null 2>&1
|
||||
if [ $? = 2 ]
|
||||
then __notice_curl() { curl -sS "$@"; }
|
||||
else __notice_curl() { curl --no-progress-meter "$@"; }
|
||||
fi
|
||||
__notice_curl "$@"
|
||||
}
|
||||
|
||||
__notice_commaize() { # fun with POSIX shell
|
||||
while [ -n "$1" ]; do
|
||||
set -- "${1%???}" "${1#"${1%???}"},$2" "$1"
|
||||
if [ "$1" = "$3" ]; then
|
||||
set -- "" "$1$2"
|
||||
break
|
||||
fi
|
||||
done
|
||||
REPLY="${2%,}"
|
||||
}
|
||||
|
||||
__notice_escape() {
|
||||
# doesn't work in posh. it doesn't like "${1%%[$2]*}", bug?
|
||||
# warning: mksh is O(n^2) with string length!
|
||||
# note: bash is horribly slow without `export LC_ALL=C`. zsh is fastest.
|
||||
set -- "" "" "$1" "$2"
|
||||
while :; do
|
||||
set -- "$1" "${3%%[$4]*}" "$3" "$4"
|
||||
[ "$2" != "$3" ] || break
|
||||
set -- "$1$2\\" "${3#"$2"}" "$3" "$4"
|
||||
set -- "$1${2%"${2#?}"}" "$2" "${2#?}" "$4"
|
||||
done
|
||||
REPLY="$1$3"
|
||||
}
|
||||
|
||||
__notice_urlencode() {
|
||||
while test "$1"; do
|
||||
case "$1" in
|
||||
([a-zA-Z0-9~_.-]*) printf '%.1s' "$1";; # RFC 3986
|
||||
(*) printf '%%%02X' "'$1";; # bash complains but works
|
||||
esac
|
||||
set -- "${1#?}"
|
||||
done
|
||||
} 2>&- # send bash's complaints to the abyss
|
||||
|
||||
__notice_generate_id() { # wraps around every 25 years
|
||||
: "${1:?missing seed}"
|
||||
REPLY=""
|
||||
while [ "${#REPLY}" -lt 8 ]; do
|
||||
case "$(($1%13))" in
|
||||
(0) REPLY="${REPLY}a";; (1) REPLY="${REPLY}c";; (2) REPLY="${REPLY}e";;
|
||||
(3) REPLY="${REPLY}m";; (4) REPLY="${REPLY}n";; (5) REPLY="${REPLY}o";;
|
||||
(6) REPLY="${REPLY}r";; (7) REPLY="${REPLY}s";; (8) REPLY="${REPLY}u";;
|
||||
(9) REPLY="${REPLY}v";; (10) REPLY="${REPLY}w";; (11) REPLY="${REPLY}x";;
|
||||
(12) REPLY="${REPLY}z";;
|
||||
esac
|
||||
set -- "$(($1/13))"
|
||||
done
|
||||
}
|
||||
|
||||
__notice_log() {
|
||||
printf '## [%s](%s)\\n\\nUploaded %s byte%s to %s [(aux)](%s) with hashes:\\n* sha1sum: `%s`' \
|
||||
"$sanitized" "$normal" "$pretty" "$fancy" "$target" "$aux" "$sha1"
|
||||
}
|
||||
|
||||
# __notice_upload_to_...
|
||||
# org_c_net_paste 50000000 or 47 MiB (approx)
|
||||
# se_uguu 67108864 or 64 MiB
|
||||
# at_x0 104857600 or 100 MiB
|
||||
# com_cockfile 134217728 or 128 MiB
|
||||
# sh_envs 536870912 or 512 MiB
|
||||
# io_file 2000000000 or 1907 MiB (approx)
|
||||
# at_oshi 5000000000 or 4768 MiB (approx)
|
||||
# com_bashupload 50000000000 or 47 GiB (approx)
|
||||
# net_filebin unlimited?
|
||||
|
||||
__notice_upload_to_org_c_net_paste() {
|
||||
# defaults: 180 days, permanent (remains after download)
|
||||
# TODO: retrieve deletion key from json response (see docs).
|
||||
# WARNING: there seems to be a bug where files with a hash collision
|
||||
# are not uploaded, and you get someone else's file instead!
|
||||
[ "${bytes:-0}" -le 50000000 ] || return 128 # approx, untested
|
||||
target=paste.c-net.org
|
||||
#normal="$(__notice_curl -gT "$1" "https://$target")" || return
|
||||
normal="$(__notice_curl -g --data-binary "@$filepath" -H "X-FileName: ${1##*/}" "https://$target")" || return
|
||||
normal="https:${normal#*http*:}"; normal="${normal%%[!!-~]*}"
|
||||
aux="$normal"
|
||||
}
|
||||
|
||||
__notice_upload_to_io_file() {
|
||||
# defaults: 14 days, ephemeral (deletes after 1 download)
|
||||
# wget should use --content-disposition when downloading
|
||||
[ "${bytes:-0}" -le 2000000000 ] || return 128 # approx, untested
|
||||
target=file.io
|
||||
normal="$(__notice_curl -F "file=@$1" "https://$target")" || return
|
||||
[ "${normal#'{"success":true,"status":200,'}" ] || return
|
||||
normal="https:${normal#*\"link\":\"https:}"; normal="${normal%%[\"]*}"
|
||||
aux="$normal" # no direct link, i think it's based on User-Agent
|
||||
}
|
||||
|
||||
__notice_upload_to_at_oshi() {
|
||||
# defaults: 1 day, semi-permanent (remains up to 1000 downloads?)
|
||||
# configured: 14 days instead
|
||||
# TODO: retrieve admin URL from response (suffixed with " [Admin]")
|
||||
# NOTE: spaces are automatically converted (by the server) to underscores.
|
||||
[ "${bytes:-0}" -le 5000000000 ] || return 128 # approx, untested
|
||||
target=oshi.at
|
||||
normal="$(__notice_curl -fF "f=@$1" -F expire=20160 "https://$target")" || return
|
||||
normal="https:${normal##*DL: http*:}"; normal="${normal%%[!!-~]*}"
|
||||
aux="$normal"
|
||||
}
|
||||
|
||||
__notice_upload_to_com_bashupload() {
|
||||
# defaults: 3 days, ephemeral (deletes after 1 download)
|
||||
# it also seems to accept `-F file=blah` multipart form-data
|
||||
# note that filenames with spaces are treated as if no filename was given!
|
||||
# TODO: when name contains spaces, replace with underscores and append to URL?
|
||||
[ "${bytes:-0}" -le 50000000000 ] || return 128 # approx, untested
|
||||
target=bashupload.com
|
||||
# https://$target/${${1##*/}// /%20}
|
||||
normal="$(__notice_curl -gT "$1" "https://$target")" || return
|
||||
normal="https:${normal#*http*:}"; normal="${normal%%[!!-~]*}"
|
||||
aux="$normal?download=1"
|
||||
}
|
||||
|
||||
__notice_upload_to_net_filebin() {
|
||||
# defaults: 7 days, permament (but can be deleted by anyone with the link)
|
||||
# note that the site says 6 days, but this is rounded down. the API shows 7 days.
|
||||
# spaces are converted to underscores, and perhaps other characters are as well.
|
||||
# note that you need curl -L to retrieve the files; they redirect to an s3 store.
|
||||
target=filebin.net
|
||||
__notice_generate_id "$(date -u +%s)" || return
|
||||
aux="https://$target/$REPLY"
|
||||
#normal="$(__notice_curl -gfT "$1" "$aux/$(__notice_urlencode ${1##*/})")" || return
|
||||
normal="$(__notice_curl -gfT "$1" "$aux/")" || return
|
||||
normal="${normal##*\"filename\": \"}"; normal="$aux/${normal%%\"*}"
|
||||
# optional: lock the bin so nobody can edit it, but anyone can still delete it.
|
||||
curl -sSX PUT "$aux" >/dev/null || true
|
||||
}
|
||||
|
||||
__notice_upload_to_at_x0() {
|
||||
# defaults: 100 days, permanent
|
||||
# note that file retention decreases as file size increases.
|
||||
# 100 MiB files are kept for 3 days, and 0 byte files are kept for 100 days.
|
||||
# filenames are randomized. cannot manually delete nor specify expiry.
|
||||
[ "${bytes:-0}" -le 104857600 ] || return 128
|
||||
target=x0.at
|
||||
normal="$(__notice_curl -fF "file=@$1" "https://$target")" || return
|
||||
aux="$normal"
|
||||
}
|
||||
|
||||
__notice_upload_to_se_uguu() {
|
||||
# defaults: 3 hours, permanent
|
||||
# filenames are randomized. cannot manually delete nor specify expiry.
|
||||
[ "${bytes:-0}" -le 67108864 ] || return 128
|
||||
target=uguu.se
|
||||
normal="$(__notice_curl -fF "files[]=@$1" "https://$target/upload?output=text")" || return
|
||||
aux="$normal"
|
||||
}
|
||||
|
||||
__notice_upload_to_com_cockfile() {
|
||||
# defaults: 12 hours, permanent
|
||||
# filenames are randomized. cannot manually delete nor specify expiry.
|
||||
[ "${bytes:-0}" -le 134217728 ] || return 128
|
||||
target=cockfile.com
|
||||
normal="$(__notice_curl -fF "files[]=@$1" "https://$target/upload.php?output=text")" || return
|
||||
aux="$normal"
|
||||
}
|
||||
|
||||
__notice_upload_to_sh_envs() {
|
||||
# configured: 14 days, permanent (TODO: add "defaults" to match other docs)
|
||||
# does not remember filenames in any capacity, BUT we can tack on our own to the URL.
|
||||
# you can delete files if you extract the X-Token field from the response HTTP headers.
|
||||
# banned MIME types: application/java-archive, application/java-vm
|
||||
[ "${bytes:-0}" -le 536870912 ] || return 128
|
||||
target=envs.sh
|
||||
normal="$(__notice_curl -fF "file=@$1" -Fsecret= -Fexpires=336 "https://$target")" || return
|
||||
aux="$normal"
|
||||
normal="$normal/${1##*/}"
|
||||
}
|
||||
|
||||
__notice_retrying() {
|
||||
case $? in
|
||||
(0) return 0;;
|
||||
# https://curl.se/libcurl/c/libcurl-errors.html
|
||||
(127)
|
||||
interrupt=1
|
||||
__notice_warn "interrupted, exiting."
|
||||
return 0;;
|
||||
(128)
|
||||
__notice_warn "file unsuitable for $target, skipping to next service..."
|
||||
return 1;;
|
||||
(*)
|
||||
__notice_warn "failed to upload to $target, trying next service..."
|
||||
return 1;;
|
||||
esac
|
||||
}
|
||||
|
||||
__notice_upload() {
|
||||
unset REPLY aux bytes fancy file filepath interrupt normal pretty sanitized sha1 target
|
||||
file="${1:-missing argument}"
|
||||
|
||||
file="$(readlink -f "$file")" || return 2 # also converts `\`s to `/`s
|
||||
# i have no idea why, but mingw64 curl on msys2 is replacing each unicode codepoint with a question mark.
|
||||
# the irony is that it seems to be properly decoding the UTF-8 encoding and then replacing it all anyway.
|
||||
[ -d /C ] && filepath="$(LC_ALL= cygpath -ws "$file")" || filepath="$file"
|
||||
|
||||
REPLY="${file##*/}"
|
||||
# ksh and mksh dictate that the characters must be in this order:
|
||||
__notice_escape "$REPLY" '][!#()*+.<>_`{|}\\\-'
|
||||
__notice_escape "$REPLY" '\\"'
|
||||
sanitized="$REPLY"
|
||||
|
||||
bytes="$(du -b -- "$file")" || return 2
|
||||
sha1="$(sha1sum -- "$file")" || return 2
|
||||
bytes="${bytes%%[!!-~]*}"
|
||||
sha1="${sha1%%[!!-~]*}"
|
||||
|
||||
__notice_commaize "$bytes"; pretty="$REPLY"
|
||||
test "$bytes" -ge 0 || return 2
|
||||
if [ "$bytes" -ge 10200547328 ]; then
|
||||
fancy="s ($(( (bytes + 536870912) / 1073741824)) GiB)"
|
||||
elif [ "$bytes" -ge 9961472 ]; then
|
||||
fancy="s ($(( (bytes + 524288) / 1048576)) MiB)"
|
||||
elif [ "$bytes" -ge 9728 ]; then
|
||||
fancy="s ($(( (bytes + 512) / 1024)) KiB)"
|
||||
elif [ "$bytes" -ne 1 ]; then
|
||||
fancy="s"
|
||||
fi
|
||||
|
||||
REPLY=
|
||||
__notice_upload_to_sh_envs "$file" || __notice_retrying || \
|
||||
__notice_upload_to_net_filebin "$file" || __notice_retrying || \
|
||||
__notice_upload_to_at_oshi "$file" || __notice_retrying || \
|
||||
__notice_upload_to_org_c_net_paste "$file" || __notice_retrying || \
|
||||
__notice_upload_to_io_file "$file" || __notice_retrying || \
|
||||
__notice_upload_to_com_bashupload "$file" || __notice_retrying || \
|
||||
{
|
||||
__notice_warn "failed to upload to every service, exiting."
|
||||
return 1
|
||||
}
|
||||
[ "$interrupt" != 1 ] || return 127
|
||||
REPLY="$(__notice_log)"
|
||||
return 0
|
||||
}
|
||||
|
||||
__notice() {
|
||||
unset LC_ALL REPLY aux code message normal title token url
|
||||
export LC_ALL=C
|
||||
url='https://eaguru.guru/gotify/message?token='
|
||||
#token="$(cat ~/.gotify.secret)" || return
|
||||
read -r token <~/.gotify.secret
|
||||
test "$token" || return # TODO: give an actual error message.
|
||||
if [ $# != 1 ] && [ $# != 2 ]; then
|
||||
printf 'usage:\n' >&2
|
||||
printf ' %s %s\n' >&2 "$0" '{message}' "$0" '{title} {message}' "$0" '@{file}'
|
||||
return 64
|
||||
fi
|
||||
|
||||
[ $# != 2 ] || { title="$1"; shift ;}
|
||||
message="${1:?missing message}"
|
||||
if [ $# = 1 ] && [ "${message#@}" != "$message" ]; then
|
||||
__notice_upload "${message#@}" || return
|
||||
printf '%s\n' >&2 "$normal"
|
||||
fi
|
||||
|
||||
set -- -qLo /dev/null -w '%{http_code}'
|
||||
set -- "$@" "$url$token"
|
||||
if [ -n "$REPLY" ]; then
|
||||
set -- "$@" --data '{"title": "New file uploaded", "message": "'"$REPLY"'", "extras": {"client::display": {"contentType": "text/markdown"}, "client::notification": {"click": {"url": "'"$aux"'"}}}}'
|
||||
set -- "$@" -H 'Content-Type: application/json'
|
||||
else
|
||||
[ -z "$title" ] || set -- "$@" --form-string "title=$title"
|
||||
[ -z "$message" ] || set -- "$@" --form-string "message=$message"
|
||||
fi
|
||||
set -- "$@" -H "Accept: application/json"
|
||||
|
||||
if code="$(__notice_curl "$@")" && [ "$code" = 200 ]; then
|
||||
:
|
||||
else
|
||||
__notice_warn "failed to upload message to ${url%%\?*} (\$code=$code, \$?=$?)"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
notice()(__notice "$@")
|
||||
[ -n "${preload+-}" ] || __notice "$@"
|
||||
|
||||
# cursed modeline:
|
||||
# vim:ft=bash ts=3 sw=3 noet sts=3
|
Loading…
Reference in a new issue