Spaces:
Sleeping
Sleeping
File size: 6,994 Bytes
8ed4d8b 9b5dfdf 8ed4d8b 9f8a082 8ed4d8b 9f8a082 8ed4d8b ca04d92 f013923 ca04d92 a795742 ca04d92 a795742 ca04d92 f013923 ca04d92 f013923 8ed4d8b 9f8a082 8ed4d8b 002a6d2 8ed4d8b 002a6d2 8ed4d8b 002a6d2 8ed4d8b 002a6d2 8ed4d8b 002a6d2 8ed4d8b 002a6d2 8ed4d8b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | #!/bin/bash
# Define paths
CONFIG_PATH="/tmp/rclone.conf"
DB_PATH="/tmp/filebrowser.db"
DATA_DIR="/data"
# Check if RCLONE_CONFIG_DATA secret is set
if [ -z "$RCLONE_CONFIG_DATA" ]; then
echo "RCLONE_CONFIG_DATA is missing. Starting setup guide server on port 7860..."
# Start a simple python server to show the configuration guide
python3 -m http.server 7860 --directory /home/user/setup_guide
exit 0
fi
# Write the rclone config file
echo "$RCLONE_CONFIG_DATA" > "$CONFIG_PATH"
chmod 600 "$CONFIG_PATH"
# Extract the remote name dynamically using Python (robust against newlines and spaces)
REMOTE_NAME=$(python3 -c "
import configparser
config = configparser.ConfigParser()
try:
config.read('$CONFIG_PATH')
sections = config.sections()
if sections:
print(sections[0].strip())
else:
print('')
except Exception:
print('')
")
if [ -z "$REMOTE_NAME" ]; then
echo "Failed to parse remote name from rclone config. Using fallback 'gdrive'."
REMOTE_NAME="gdrive"
fi
# Determine the remote path (root or subfolder) to prevent exceeding Hugging Face's 50GB limit
if [ -n "$RCLONE_REMOTE_PATH" ]; then
# Trim leading/trailing slashes
CLEAN_PATH=$(echo "$RCLONE_REMOTE_PATH" | sed -e 's/^\///' -e 's/\/$//')
REMOTE_PATH="$REMOTE_NAME:$CLEAN_PATH"
echo "Using subfolder path: $REMOTE_PATH"
else
REMOTE_PATH="$REMOTE_NAME:"
echo "Using root path: $REMOTE_PATH"
fi
# Set shared-with-me flag if requested
SHARED_FLAG=""
if [ "$RCLONE_SHARED_WITH_ME" = "true" ]; then
SHARED_FLAG="--drive-shared-with-me"
echo "Rclone will access 'Shared with me' files/folders."
fi
# Ensure SQLite database file exists so inotifywait can monitor it
touch "$DB_PATH"
# 1. Download database from Google Drive if it exists
echo "Checking for persistent database on Google Drive..."
rclone copyto "$REMOTE_PATH/.filebrowser.db" "$DB_PATH" --config "$CONFIG_PATH" --drive-skip-shortcuts --drive-acknowledge-abuse $SHARED_FLAG || true
# Initialize config if export fails (e.g. database doesn't exist or is empty)
if ! filebrowser config export -d "$DB_PATH" >/dev/null 2>&1; then
echo "Initializing database..."
filebrowser config init -d "$DB_PATH"
filebrowser config set --root "$DATA_DIR" -d "$DB_PATH"
fi
# Enable Command Runner (shell execution) globally
echo "Enabling Command Runner globally..."
filebrowser config set --disable-exec=false --commands "zip,unzip,wget,curl,ls" -d "$DB_PATH"
# Configure admin password and execution permissions via FILEBROWSER_PASSWORD secret if set
if [ -n "$FILEBROWSER_PASSWORD" ]; then
echo "FILEBROWSER_PASSWORD secret is set. Configuring admin password..."
# Set or update the admin user password and execution permissions
echo "Setting admin user password..."
if filebrowser users update admin --password "$FILEBROWSER_PASSWORD" --commands "zip,unzip,wget,curl,ls" --perm.execute=true -d "$DB_PATH" >/dev/null 2>&1; then
echo "Admin password and permissions updated successfully."
else
echo "Admin user not found. Creating admin user with custom password..."
filebrowser users add admin "$FILEBROWSER_PASSWORD" --perm.admin --perm.execute=true --commands "zip,unzip,wget,curl,ls" -d "$DB_PATH"
fi
else
# Even if password secret is not set, ensure default admin has execute permissions
echo "Updating default admin user commands and permissions..."
filebrowser users update admin --commands "zip,unzip,wget,curl,ls" --perm.execute=true -d "$DB_PATH" || true
fi
# 2. Download files from Google Drive to local /data directory
echo "Syncing files from Google Drive..."
rclone copy "$REMOTE_PATH" "$DATA_DIR" --config "$CONFIG_PATH" --drive-skip-shortcuts --drive-acknowledge-abuse $SHARED_FLAG || true
# 3. Start background sync loops
# Loop A: Sync files in /data to Google Drive when modified (Debounced & Robust)
(
echo "Starting file sync daemon..."
LAST_EVENT_FILE="/tmp/last_event_time"
PENDING_FILE="/tmp/sync_pending"
DEBOUNCE_SECS=10
# Clear any old state
rm -f "$LAST_EVENT_FILE" "$PENDING_FILE"
# Start inotifywait in monitor mode to ensure we don't miss any events while syncing
inotifywait -r -m -e close_write,delete,move "$DATA_DIR" 2>/dev/null | while read -r _; do
date +%s > "$LAST_EVENT_FILE"
if [ ! -f "$PENDING_FILE" ]; then
touch "$PENDING_FILE"
fi
done &
# Background runner that waits for a quiet period before syncing
while true; do
if [ -f "$PENDING_FILE" ]; then
last_time=$(cat "$LAST_EVENT_FILE" 2>/dev/null || echo 0)
now=$(date +%s)
elapsed=$((now - last_time))
if [ "$elapsed" -ge "$DEBOUNCE_SECS" ]; then
rm -f "$PENDING_FILE"
echo "Changes detected in $DATA_DIR, syncing to Google Drive ($REMOTE_PATH)..."
if rclone copy "$DATA_DIR" "$REMOTE_PATH" --config "$CONFIG_PATH" --drive-skip-shortcuts --drive-acknowledge-abuse $SHARED_FLAG; then
echo "File sync successful."
else
echo "File sync failed or partially completed (e.g. active uploads). Will retry..."
# Set last event to now to debounce the next retry
date +%s > "$LAST_EVENT_FILE"
touch "$PENDING_FILE"
fi
fi
fi
sleep 2
done
) &
# Loop B: Sync database /tmp/filebrowser.db to Google Drive when modified (Debounced & Robust)
(
echo "Starting database sync daemon..."
DB_LAST_EVENT="/tmp/db_last_event"
DB_PENDING="/tmp/db_sync_pending"
DEBOUNCE_SECS=3
# Clear any old state
rm -f "$DB_LAST_EVENT" "$DB_PENDING"
# Start inotifywait in monitor mode
inotifywait -m -e modify "$DB_PATH" 2>/dev/null | while read -r _; do
date +%s > "$DB_LAST_EVENT"
if [ ! -f "$DB_PENDING" ]; then
touch "$DB_PENDING"
fi
done &
# Background runner for database sync
while true; do
if [ -f "$DB_PENDING" ]; then
last_time=$(cat "$DB_LAST_EVENT" 2>/dev/null || echo 0)
now=$(date +%s)
elapsed=$((now - last_time))
if [ "$elapsed" -ge "$DEBOUNCE_SECS" ]; then
rm -f "$DB_PENDING"
echo "Database modified, uploading to Google Drive ($REMOTE_PATH)..."
if rclone copyto "$DB_PATH" "$REMOTE_PATH/.filebrowser.db" --config "$CONFIG_PATH" $SHARED_FLAG; then
echo "Database sync successful."
else
echo "Database sync failed. Will retry..."
date +%s > "$DB_LAST_EVENT"
touch "$DB_PENDING"
fi
fi
fi
sleep 1
done
) &
# 4. Start File Browser
echo "Starting File Browser on port 7860..."
filebrowser --port 7860 --address 0.0.0.0 --database "$DB_PATH" --root "$DATA_DIR"
|