getpkg/sos/sos
Your Name c1ca52ec66
All checks were successful
Build-Test-Publish / build (push) Successful in 16s
'Generic Commit'
2025-06-15 21:58:40 +12:00

163 lines
4.3 KiB
Bash
Executable File

#!/bin/bash
set -euo pipefail
# get dropshell
TEMP_DIR=$(mktemp -d)
ARCH=$(uname -m)
curl -L -s -o "${TEMP_DIR}/dropshell" "https://getbin.xyz/dropshell.${ARCH}" || die "Failed to download dropshell"
chmod +x "${TEMP_DIR}/dropshell"
trap 'rm -rf "${TEMP_DIR}"' EXIT
DROPSHELL="${TEMP_DIR}/dropshell"
function show_help() {
cat << EOF
sos is a script to upload files to a simple object storage server.
Usage:
sos upload <server> <file> <label:tag> [label:tag ...]
Example:
sos upload tools.dropshell.app ./file.txt file:latest
This will upload the file to the server, and return the download URL.
Environment variables:
SOS_WRITE_TOKEN: The write token to use for the upload. If not set,
the script will look in $HOME/.config/sos/write_token.txt.
EOF
exit 0
}
function die() {
echo "FATAL:"
echo "$@"
exit 1
}
function datetime() {
date -u +"%Y.%m%d.%H%M"
}
function upload() {
if [ "$#" -lt 3 ]; then
echo "Usage: sos upload <server> <file> <label:tag> [label:tag ...]"
exit 1
fi
server=$1
file=$2
first_label=$3
LABELTAGS=("$first_label")
[[ "$first_label" =~ : ]] || die "Label $first_label does not contain a tag!"
shift 3
for label in "$@"; do
[[ "$label" =~ : ]] || die "Label $label does not contain a tag!"
LABELTAGS+=("$label")
done
# check if file contains :
[[ ! "$file" =~ : ]] || die "File contains : - this is not allowed!"
[ -f "$file" ] || die "File not found: $file"
# upload the file
TARGET_SERVER="https://$server"
echo "Uploading $file to $TARGET_SERVER"
DATETIME=$(datetime)
# deduplicate the labeltags
mapfile -t LABELTAGS < <(printf "%s\n" "${LABELTAGS[@]}" | sort -u)
LABELTAGS_JSON=$(printf '"%s",' "${LABELTAGS[@]}")
LABELTAGS_JSON="[${LABELTAGS_JSON%,}]"
# trip whitespace from the file path
LOCALHASH=$("${DROPSHELL}" hash "${file}" | tr -d '[:space:]')
echo "Local hash: $LOCALHASH"
METADATA_JSON=$(cat <<EOF
{
"labeltags": $LABELTAGS_JSON,
"description": "Uploaded by sos",
"version": "$DATETIME"
}
EOF
)
if [ -n "${SOS_WRITE_TOKEN:-}" ]; then
WRITE_TOKEN="$SOS_WRITE_TOKEN"
else
TOKENPATH="$HOME/.config/sos/write_token.txt"
if [ ! -f "$TOKENPATH" ]; then
die "Token file not found in environment variable SOS_WRITE_TOKEN or $TOKENPATH. Please create it and put your write token in it."
fi
WRITE_TOKEN=$(cat "$TOKENPATH")
fi
EXISTSJSON=$(eval "curl -s \"https://$server/exists/$LOCALHASH\"") || die "Failed to check if file exists"
DOESEXIT=$(echo "$EXISTSJSON" | jq -r '.exists')
HASH=""
if [ "$DOESEXIT" == "true" ]; then
echo "File already exists, skipping upload"
# UPDATE the metadata - this approach recommended by SWE-1 so we're not using form data...
# curl -X PUT \
# -H "Authorization: Bearer ${WRITE_TOKEN}" \
# -H "Content-Type: application/json" \
# -d "{\"hash\":\"${LOCALHASH}\", \"metadata\":${METADATA_JSON}}" \
# "$TARGET_SERVER/update" \
# || die "Failed to update metadata at $TARGET_SERVER/update"
curl -X PUT -H "Authorization: Bearer ${WRITE_TOKEN}" \
-F "metadata=${METADATA_JSON}" \
-F "hash=${LOCALHASH}" \
"$TARGET_SERVER/update" \
|| die "Failed to upload $file to $TARGET_SERVER/update"
else
# UPLOAD the file + metadata
curl -X PUT -H "Authorization: Bearer ${WRITE_TOKEN}" \
-F "metadata=${METADATA_JSON}" \
-F "file=@${file}" \
"$TARGET_SERVER/upload" \
|| die "Failed to upload $file to $TARGET_SERVER/upload"
fi
echo " "
echo " "
JSON1=$(eval "curl -s \"https://$server/hash/$first_label\"")
HASH=$(echo "$JSON1" | jq -r '.hash')
JSON2=$(eval "curl -s \"https://$server/meta/$HASH\"") || die "Failed to get meta for $HASH"
FILENAME=$(echo "$JSON2" | jq -r '.metadata.filename')
echo "Metadata:"
echo "$JSON2" | jq
echo " "
echo "Download URL: https://$server/$first_label > $FILENAME"
echo "Alternative: https://$server/$HASH > $FILENAME"
}
# if no arguments, show help
[ "$#" -gt 0 ] || show_help
CMD="$1"
shift
if [ "$CMD" == "upload" ]; then
upload "$@"
exit $?
fi
die "Unknown command: $CMD"