Something went wrong. Try again.
Tools for the Atmosphere tools.slices.network
quickslice atproto html
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234#!/usr/bin/env bashset -euo pipefail
# Bunny CDN Deploy Script for tools.slices.network# Syncs .html files to Bunny Storage with clean URLs (no .html extension)
# Colors for outputRED='\033[0;31m'GREEN='\033[0;32m'YELLOW='\033[1;33m'NC='\033[0m' # No Color
# CountersUPLOADED=0DELETED=0
# Parse argumentsDRY_RUN=falseVERBOSE=false
while [[ $# -gt 0 ]]; do case $1 in --dry-run) DRY_RUN=true shift ;; --verbose|-v) VERBOSE=true shift ;; *) echo -e "${RED}Unknown option: $1${NC}" exit 1 ;; esacdone
# Load .env file if it existsif [ -f .env ]; then set -a source .env set +afi
# Required environment variables: "${BUNNY_API_KEY:?BUNNY_API_KEY environment variable is required}": "${BUNNY_STORAGE_PASSWORD:?BUNNY_STORAGE_PASSWORD environment variable is required}": "${BUNNY_STORAGE_ZONE:?BUNNY_STORAGE_ZONE environment variable is required}": "${BUNNY_STORAGE_HOST:?BUNNY_STORAGE_HOST environment variable is required}": "${BUNNY_PULLZONE_ID:?BUNNY_PULLZONE_ID environment variable is required}"
# ConfigurationSTORAGE_URL="https://${BUNNY_STORAGE_HOST}/${BUNNY_STORAGE_ZONE}"
echo "Bunny CDN Deploy - tools.slices.network"echo "========================================"echo "Storage Zone: ${BUNNY_STORAGE_ZONE}"if [ "$DRY_RUN" = true ]; then echo -e "${YELLOW}DRY RUN MODE - No changes will be made${NC}"fiecho ""
# Upload a single file (strips .html extension for clean URLs, keeps others as-is)upload_file() { local local_path="$1" local filename filename=$(basename "$local_path") # Strip .html extension for clean URLs, keep other extensions local remote_name if [[ "$filename" == *.html ]]; then remote_name="${filename%.html}" else remote_name="$filename" fi
if [ "$VERBOSE" = true ]; then echo " Uploading: ${filename} -> ${remote_name}" fi
if [ "$DRY_RUN" = true ]; then ((UPLOADED++)) return 0 fi
local response local http_code
# Determine content type local content_type="text/html" if [[ "$filename" == *.js ]]; then content_type="application/javascript" fi
response=$(curl -s -w "\n%{http_code}" -X PUT \ "${STORAGE_URL}/${remote_name}" \ -H "AccessKey: ${BUNNY_STORAGE_PASSWORD}" \ -H "Content-Type: ${content_type}" \ --data-binary "@${local_path}")
http_code=$(echo "$response" | tail -n1)
if [[ "$http_code" =~ ^2 ]]; then ((UPLOADED++)) return 0 else echo -e "${RED}Failed to upload ${filename}: HTTP ${http_code}${NC}" echo "$response" | head -n -1 return 1 fi}
# List all files in remote storagelist_remote_files() { local response response=$(curl -s -X GET "${STORAGE_URL}/" \ -H "AccessKey: ${BUNNY_STORAGE_PASSWORD}" \ -H "Accept: application/json")
echo "$response" | jq -r '.[] | select(.IsDirectory == false) | .ObjectName' 2>/dev/null}
# Delete a single file from remotedelete_file() { local remote_name="$1"
if [ "$VERBOSE" = true ]; then echo " Deleting: ${remote_name}" fi
if [ "$DRY_RUN" = true ]; then ((DELETED++)) return 0 fi
local http_code http_code=$(curl -s -o /dev/null -w "%{http_code}" -X DELETE \ "${STORAGE_URL}/${remote_name}" \ -H "AccessKey: ${BUNNY_STORAGE_PASSWORD}")
if [[ "$http_code" =~ ^2 ]]; then ((DELETED++)) return 0 else echo -e "${RED}Failed to delete ${remote_name}: HTTP ${http_code}${NC}" return 1 fi}
# Purge pull zone cachepurge_cache() { echo "Purging CDN cache..."
if [ "$DRY_RUN" = true ]; then echo -e "${YELLOW} Would purge pull zone ${BUNNY_PULLZONE_ID}${NC}" return 0 fi
local http_code http_code=$(curl -s -o /dev/null -w "%{http_code}" -X POST \ "https://api.bunny.net/pullzone/${BUNNY_PULLZONE_ID}/purgeCache" \ -H "AccessKey: ${BUNNY_API_KEY}" \ -H "Content-Type: application/json")
if [[ "$http_code" =~ ^2 ]]; then echo -e "${GREEN} Cache purged successfully${NC}" return 0 else echo -e "${RED} Failed to purge cache: HTTP ${http_code}${NC}" return 1 fi}
# ============================================# MAIN EXECUTION# ============================================
# Find all .html and .js files in root directoryDEPLOY_FILES=$(find . -maxdepth 1 \( -name "*.html" -o -name "*.js" \) -type f 2>/dev/null)
if [ -z "$DEPLOY_FILES" ]; then echo -e "${YELLOW}No .html or .js files found in current directory${NC}" exit 0fi
# Build list of expected remote names (without .html extension)LOCAL_NAMES_LIST=$(mktemp)trap "rm -f $LOCAL_NAMES_LIST" EXIT
# Step 1: Upload all local filesecho "Uploading files..."echo "$DEPLOY_FILES" | while read -r file; do filename=$(basename "$file") if [[ "$filename" == *.html ]]; then remote_name="${filename%.html}" else remote_name="$filename" fi echo "$remote_name" >> "$LOCAL_NAMES_LIST" upload_file "$file"done
echo ""
# Step 2: Delete orphaned remote filesecho "Checking for orphaned files..."REMOTE_FILES=$(list_remote_files)
if [ -n "$REMOTE_FILES" ]; then while IFS= read -r remote_file; do if [ -z "$remote_file" ]; then continue fi if ! grep -qxF "$remote_file" "$LOCAL_NAMES_LIST"; then delete_file "$remote_file" fi done <<< "$REMOTE_FILES"fi
echo ""
# Step 3: Purge CDN cachepurge_cache
# Summaryecho ""echo "========================================"echo -e "${GREEN}Deploy complete!${NC}"echo " Uploaded: ${UPLOADED} files"echo " Deleted: ${DELETED} files"if [ "$DRY_RUN" = true ]; then echo -e "${YELLOW} (DRY RUN - no actual changes made)${NC}"fiecho "========================================"