118 lines
4.7 KiB
Python
Executable File

#!/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()