Updated script to sync and archive playlist files from a remote system
This commit is contained in:
parent
faf42af274
commit
362603d160
35
scripts/NOTES.md
Normal file
35
scripts/NOTES.md
Normal file
@ -0,0 +1,35 @@
|
||||
# Beat Saber Playlist Scripts
|
||||
|
||||
Tools for managing Beat Saber playlists and custom maps across Windows and other systems.
|
||||
|
||||
## Map Installation
|
||||
|
||||
To copy a custom map to Beat Saber:
|
||||
```powershell
|
||||
Copy-Item -Path "map_folder" -Destination "C:\Program Files (x86)\Steam\steamapps\common\Beat Saber\Beat Saber_Data\CustomLevels\" -Recurse
|
||||
```
|
||||
|
||||
## Playlist Sync Script
|
||||
`sabersync.py` is a utility script that:
|
||||
- Syncs `.bplist` files between systems
|
||||
- Archives old/deleted playlists
|
||||
- Optionally syncs Beat Saber video recordings
|
||||
|
||||
Usage:
|
||||
```bash
|
||||
./sabersync.py [--video] [--help]
|
||||
```
|
||||
|
||||
Options:
|
||||
- `--video`: Sync video recordings from the remote system
|
||||
- `--help`: Show help message
|
||||
|
||||
The script expects:
|
||||
- SSH access to a Windows machine with alias `winroar`
|
||||
- Beat Saber installed at standard Steam paths
|
||||
- Playlists in `BSManager/BSInstances/1.39.1/Playlists/`
|
||||
|
||||
When run with `--video`, it will:
|
||||
1. Copy videos from the remote system
|
||||
2. Wait for confirmation
|
||||
3. Clean up remote video files after transfer
|
118
scripts/sabersync.py
Executable file
118
scripts/sabersync.py
Executable file
@ -0,0 +1,118 @@
|
||||
#!/usr/bin/env python
|
||||
# Helper script to backup playlists and copy new ones over
|
||||
|
||||
import argparse
|
||||
import subprocess
|
||||
import os
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
import sys
|
||||
import shlex
|
||||
|
||||
def usage():
|
||||
print("Usage: {} [--video]".format(sys.argv[0]))
|
||||
sys.exit(1)
|
||||
|
||||
def run_command(command, capture_output=False, text=True):
|
||||
try:
|
||||
result = subprocess.run(command, shell=True, check=True, capture_output=capture_output, text=text)
|
||||
return result.stdout if capture_output else None
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Command '{command}' failed with exit code {e.returncode}")
|
||||
sys.exit(e.returncode)
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Synchronize Beat Saber playlists and optionally videos.", add_help=False)
|
||||
parser.add_argument('-v', '--video', action='store_true', help='Enable video synchronization')
|
||||
parser.add_argument('-h', '--help', action='store_true', help='Show help message and exit')
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.help:
|
||||
usage()
|
||||
|
||||
COPY_VIDEOS = args.video
|
||||
|
||||
# Define paths
|
||||
REMOTE_PLAYLISTS = "BSManager/BSInstances/1.39.1/Playlists/"
|
||||
REMOTE_PLAYLISTS_WIN = "BSManager\\BSInstances\\1.39.1\\Playlists" # For Windows SSH commands
|
||||
LOCAL_ARCHIVE_DIR = Path.home() / "archive" / "beatsaber-playlists"
|
||||
LOCAL_ARCHIVE_SUBDIR = LOCAL_ARCHIVE_DIR / "archive"
|
||||
LOCAL_BPLIST_DIR = Path.cwd()
|
||||
|
||||
# Ensure archive subdirectory exists
|
||||
LOCAL_ARCHIVE_SUBDIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Check for local *.bplist files and sync to remote using scp
|
||||
bplist_files = list(LOCAL_BPLIST_DIR.glob("*.bplist"))
|
||||
if bplist_files:
|
||||
print("Starting synchronization of .bplist files to remote using scp...")
|
||||
# Build file string with proper quoting using shlex.quote, so wildcard expansion isn't needed
|
||||
files_str = " ".join(shlex.quote(str(file)) for file in bplist_files)
|
||||
scp_sync_upload = f"scp {files_str} winroar:\"{REMOTE_PLAYLISTS}\""
|
||||
run_command(scp_sync_upload)
|
||||
# Remove local *.bplist files after successful transfer
|
||||
for f in bplist_files:
|
||||
f.unlink()
|
||||
print(f"Removed local file: {f.name}")
|
||||
|
||||
# Fetch list of remote *.bplist files
|
||||
print("Fetching list of remote .bplist files...")
|
||||
ssh_command = f'ssh winroar "cd {REMOTE_PLAYLISTS_WIN} && dir /b *.bplist"'
|
||||
remote_bplist = run_command(ssh_command, capture_output=True)
|
||||
remote_bplist_files = set(remote_bplist.strip().split('\n')) if remote_bplist else set()
|
||||
|
||||
# Fetch list of local archive *.bplist files
|
||||
print("Fetching list of local archived .bplist files...")
|
||||
local_archive_files = set(f.name for f in LOCAL_ARCHIVE_DIR.glob("*.bplist"))
|
||||
|
||||
# Determine deleted files (present locally but not remotely)
|
||||
deleted_files = local_archive_files - remote_bplist_files
|
||||
if deleted_files:
|
||||
print("Identifying deleted playlists...")
|
||||
for file in deleted_files:
|
||||
local_file = LOCAL_ARCHIVE_DIR / file
|
||||
destination_file = LOCAL_ARCHIVE_SUBDIR / file
|
||||
if local_file.exists():
|
||||
if destination_file.exists():
|
||||
destination_file.unlink() # Remove existing file to allow overwrite
|
||||
print(f"Overwriting existing archived file: {file}")
|
||||
shutil.move(str(local_file), str(destination_file))
|
||||
print(f"Archived deleted playlist: {file}")
|
||||
else:
|
||||
print("No deleted playlists found.")
|
||||
|
||||
# Sync remote *.bplist to local archive directory
|
||||
print("Downloading current remote .bplist files to local archive...")
|
||||
scp_sync_download = (
|
||||
f"scp winroar:\"{REMOTE_PLAYLISTS}*.bplist\" \"{LOCAL_ARCHIVE_DIR}/\""
|
||||
)
|
||||
run_command(scp_sync_download)
|
||||
print("Download complete.")
|
||||
|
||||
# Optional video synchronization
|
||||
if COPY_VIDEOS:
|
||||
print("Starting video synchronization with scp...")
|
||||
|
||||
# Define remote and local video paths
|
||||
REMOTE_VIDEOS = "/Users/pleb/Videos/Beat Saber/"
|
||||
LOCAL_DOWNLOADS = Path.home() / "Downloads" / "Beat Saber"
|
||||
|
||||
# Ensure local downloads directory exists
|
||||
LOCAL_DOWNLOADS.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Construct scp command to copy videos from remote to local Downloads folder
|
||||
scp_sync_videos = (
|
||||
f"scp -r winroar:\"{REMOTE_VIDEOS}\" \"{LOCAL_DOWNLOADS}\""
|
||||
)
|
||||
run_command(scp_sync_videos)
|
||||
print("Video files synchronized successfully.")
|
||||
|
||||
input("Press [Enter] to delete videos on winroar.")
|
||||
|
||||
# Delete videos on remote after confirmation
|
||||
ssh_delete_command = f'ssh winroar \'rm -rf "{REMOTE_VIDEOS}"\''
|
||||
run_command(ssh_delete_command)
|
||||
print("Remote video directory deleted.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
84
scripts/sabersync.sh
Executable file
84
scripts/sabersync.sh
Executable file
@ -0,0 +1,84 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
# Function to display usage
|
||||
usage() {
|
||||
echo "Usage: $0 [--video]"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Parse command-line arguments
|
||||
COPY_VIDEOS=false
|
||||
|
||||
while [[ "$#" -gt 0 ]]; do
|
||||
case $1 in
|
||||
-v|--video)
|
||||
COPY_VIDEOS=true
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
echo "Unknown parameter passed: $1"
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -n "$(find . -maxdepth 1 -type f -name "*.bplist" -print -quit)" ]; then
|
||||
scp ./*.bplist winroar:BSManager/BSInstances/1.39.1/Playlists/
|
||||
rm -v ./*.bplist
|
||||
fi
|
||||
|
||||
##
|
||||
## Playlist Archive
|
||||
##
|
||||
|
||||
# Define remote and local directories for playlist synchronization
|
||||
REMOTE_PLAYLISTS="BSManager/BSInstances/1.39.1/Playlists/"
|
||||
LOCAL_ARCHIVE_DIR=~/archive/beatsaber-playlists/
|
||||
LOCAL_ARCHIVE_SUBDIR=~/archive/beatsaber-playlists/archive/
|
||||
PREVIOUS_LIST=~/archive/beatsaber-playlists/previous_bplist_files.txt
|
||||
|
||||
# Ensure archive subdirectory exists
|
||||
mkdir -p "$LOCAL_ARCHIVE_SUBDIR"
|
||||
|
||||
# Fetch current remote *.bplist files
|
||||
ssh winroar "cd \"${REMOTE_PLAYLISTS}\" && dir /B *.bplist" > current_bplist_files.txt
|
||||
|
||||
# Compare with previous list to find deleted files
|
||||
if [[ -f "$PREVIOUS_LIST" ]]; then
|
||||
deleted_files=$(comm -23 <(sort "$PREVIOUS_LIST") <(sort current_bplist_files.txt))
|
||||
for file in $deleted_files; do
|
||||
filename=$(basename "$file")
|
||||
if [[ -f "${LOCAL_ARCHIVE_DIR}${filename}" ]]; then
|
||||
mv "${LOCAL_ARCHIVE_DIR}${filename}" "$LOCAL_ARCHIVE_SUBDIR"
|
||||
echo "Archived deleted playlist: $filename"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Update the previous list
|
||||
mv current_bplist_files.txt "$PREVIOUS_LIST"
|
||||
|
||||
# Sync playlist files from remote to local
|
||||
scp -q winroar:"${REMOTE_PLAYLISTS}*.bplist" "$LOCAL_ARCHIVE_DIR"
|
||||
|
||||
# Optional video synchronization
|
||||
if $COPY_VIDEOS; then
|
||||
echo "Starting video synchronization..."
|
||||
|
||||
# Copy videos from remote to local Downloads folder
|
||||
scp -r winroar:"Videos/Beat Saber/" "$HOME/Downloads/"
|
||||
|
||||
echo "Video files copied successfully."
|
||||
|
||||
echo "Press [Enter] to delete videos on winroar."
|
||||
read -r
|
||||
|
||||
# Delete videos on remote after confirmation
|
||||
ssh winroar 'rmdir Videos/Beat\ Saber /q /s'
|
||||
|
||||
echo "Remote video directory deleted."
|
||||
fi
|
Loading…
x
Reference in New Issue
Block a user