Last active
July 20, 2025 21:22
-
-
Save ianchesal/34bb82dc5565eccd88f54c4f1c371d55 to your computer and use it in GitHub Desktop.
Auto-Organize Your Fractal-Bot Backups
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# ***USE*** | |
# Drop this file into the folder where you have Fractal-Bot storing your | |
# backups. Name it whatever you like. Run it from time to time and it'll | |
# sort your backups into sub-folders based on file prefixes. | |
# | |
# If you're on a Mac you can use this code as a Folder Automation action and | |
# it should work just fine and run every time a new file is created in your | |
# backup folder. | |
# | |
# ***REQUIRES*** | |
# Fractal-Bot v3.0.8 or newer | |
require 'fileutils' | |
# Add new devices you're backing up to this list | |
supported_devices = %w[FM3 III AX8 FM9 VP4] | |
supported_devices.each do |subdir| | |
next if File.directory? subdir | |
puts "Making ./#{subdir}" | |
FileUtils.mkdir_p subdir | |
end | |
Dir.glob('*.syx') do |sysexfile| | |
next unless File.file? sysexfile | |
subdir = sysexfile[0..2] | |
next unless supported_devices.include? subdir | |
puts "Moving #{sysexfile} to ./#{subdir}/" | |
FileUtils.mv(sysexfile, "./#{subdir}/#{sysexfile}") | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Fractal-Bot Backup Group Zipper | |
# | |
# This script finds SYX files matching the pattern <dirname>-<timestamp>-*.syx | |
# or <timestamp>-*.syx (for older backups), groups them by timestamp, | |
# and creates zip archives named <dirname>-<timestamp>.zip or <timestamp>.zip | |
# | |
# Usage: Run this script in a device directory (e.g., III, FM9, VP4) | |
# | |
# CAUTION: This script DELETES the original .syx files after zipping them! | |
# set -eo pipefail | |
# Get current directory name (e.g., "III", "FM9") | |
DIRNAME=$(basename "$PWD") | |
# Color output for better visibility | |
RED='\033[0;31m' | |
GREEN='\033[0;32m' | |
YELLOW='\033[1;33m' | |
BLUE='\033[0;34m' | |
NC='\033[0m' # No Color | |
echo -e "${BLUE}Fractal-Bot Backup Group Zipper${NC}" | |
echo -e "Working in directory: ${YELLOW}$DIRNAME${NC}" | |
echo | |
# Check if we have any .syx files | |
if ! ls *.syx >/dev/null 2>&1; then | |
echo -e "${RED}No .syx files found in current directory.${NC}" | |
exit 1 | |
fi | |
# Function to process files and group them | |
process_files() { | |
local pattern="$1" | |
local prefix="$2" | |
local description="$3" | |
echo -e "${BLUE}Processing $description files...${NC}" | |
# Find all unique timestamps for this pattern (extract before any files are deleted) | |
local timestamps | |
if [[ "$prefix" == "" ]]; then | |
# For older format files without prefix: YYMMDD-HHMMSS-*.syx | |
timestamps=$(ls $pattern 2>/dev/null | sed -E 's/^([0-9]{6}-[0-9]{6})-.*\.syx/\1/' | sort -u) | |
else | |
# For newer format files with prefix: DIRNAME-YYMMDD-HHMMSS-*.syx | |
timestamps=$(ls $pattern 2>/dev/null | sed -E 's/.*-([0-9]{6}-[0-9]{6})-.*\.syx/\1/' | sort -u) | |
fi | |
if [ -z "$timestamps" ]; then | |
echo -e " ${YELLOW}No $description files found.${NC}" | |
return | |
fi | |
local count=0 | |
for timestamp in $timestamps; do | |
local files | |
files=$(ls ${prefix}${timestamp}-*.syx 2>/dev/null || true) | |
if [ -n "$files" ]; then | |
local zip_name | |
if [ -n "$prefix" ] && [ "$prefix" != "$DIRNAME-" ]; then | |
zip_name="${prefix%%-}${timestamp}.zip" | |
else | |
zip_name="${DIRNAME}-${timestamp}.zip" | |
fi | |
echo -e " ${GREEN}Creating ${zip_name}${NC}" | |
echo " Files: $(echo $files | wc -w) file(s)" | |
# Create the zip file | |
if zip -q "$zip_name" $files; then | |
echo -e " ${GREEN}✓ Archive created successfully${NC}" | |
# Delete the original files | |
rm $files | |
echo -e " ${GREEN}✓ Original files deleted${NC}" | |
((count++)) | |
else | |
echo -e " ${RED}✗ Failed to create archive${NC}" | |
fi | |
fi | |
done | |
echo -e " ${GREEN}Processed $count timestamp group(s)${NC}" | |
echo | |
} | |
# Safety check: Ask user for confirmation | |
echo -e "${YELLOW}WARNING: This script will DELETE the original .syx files after zipping them!${NC}" | |
echo -e "${YELLOW}Files will be grouped by timestamp and zipped.${NC}" | |
echo | |
read -p "Do you want to continue? (y/N): " -r | |
if [[ ! $REPLY =~ ^[Yy]$ ]]; then | |
echo -e "${RED}Operation cancelled.${NC}" | |
exit 1 | |
fi | |
echo | |
# Count total files before processing | |
total_files=$(ls *.syx 2>/dev/null | wc -l) | |
echo -e "${BLUE}Found $total_files .syx files total${NC}" | |
echo | |
# Process newer format files: <DIRNAME>-YYMMDD-HHMMSS-*.syx | |
process_files "${DIRNAME}-[0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9]-*.syx" "${DIRNAME}-" "newer format (${DIRNAME}-YYMMDD-HHMMSS)" | |
# Process older format files: YYMMDD-HHMMSS-*.syx (without device prefix) | |
process_files "[0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9]-*.syx" "" "older format (YYMMDD-HHMMSS)" | |
# Count remaining files | |
if ls *.syx >/dev/null 2>&1; then | |
remaining_files=$(ls *.syx | wc -l) | |
else | |
remaining_files=0 | |
fi | |
processed_files=$((total_files - remaining_files)) | |
echo -e "${GREEN}✓ Processing complete!${NC}" | |
echo -e " Files processed: ${GREEN}$processed_files${NC}" | |
echo -e " Files remaining: ${YELLOW}$remaining_files${NC}" | |
if [ "$remaining_files" -gt 0 ]; then | |
echo | |
echo -e "${YELLOW}Remaining files (didn't match expected patterns):${NC}" | |
ls *.syx 2>/dev/null || true | |
fi | |
echo | |
echo -e "${BLUE}Created zip files:${NC}" | |
if ls *.zip >/dev/null 2>&1; then | |
ls *.zip | |
else | |
echo -e "${YELLOW}No zip files created.${NC}" | |
fi |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Fractal-Bot Yearly Archive Creator | |
# | |
# This script finds SYX files with timestamp-based filenames and creates | |
# yearly archives (YYYY.zip) by grouping files with the same year. | |
# If a yearly archive already exists, new files are added to it. | |
# | |
# Supports both formats: | |
# - Newer: DIRNAME-YYMMDD-HHMMSS-*.syx | |
# - Older: YYMMDD-HHMMSS-*.syx | |
# | |
# Usage: Run this script in a device directory (e.g., III, FM9, VP4) | |
# | |
# CAUTION: This script DELETES the original .syx files after zipping them! | |
# Get current directory name (e.g., "III", "FM9") | |
DIRNAME=$(basename "$PWD") | |
# Try to detect the actual device prefix from existing files | |
DEVICE_PREFIX="" | |
if ls *-[0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9]-*.syx >/dev/null 2>&1; then | |
# Extract the device prefix from the first matching file | |
DEVICE_PREFIX=$(ls *-[0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9]-*.syx 2>/dev/null | head -1 | sed -E 's/^([^-]+)-[0-9]{6}-.*\.syx/\1/') | |
echo -e "Detected device prefix: ${YELLOW}$DEVICE_PREFIX${NC}" | |
else | |
DEVICE_PREFIX="$DIRNAME" | |
echo -e "Using directory name as device prefix: ${YELLOW}$DEVICE_PREFIX${NC}" | |
fi | |
# Color output for better visibility | |
RED='\033[0;31m' | |
GREEN='\033[0;32m' | |
YELLOW='\033[1;33m' | |
BLUE='\033[0;34m' | |
NC='\033[0m' # No Color | |
echo -e "${BLUE}Fractal-Bot Yearly Archive Creator${NC}" | |
echo -e "Working in directory: ${YELLOW}$DIRNAME${NC}" | |
echo | |
# Check if we have any .syx files | |
if ! ls *.syx >/dev/null 2>&1; then | |
echo -e "${RED}No .syx files found in current directory.${NC}" | |
exit 1 | |
fi | |
# Function to process files and group them by year | |
process_yearly_files() { | |
local pattern="$1" | |
local prefix="$2" | |
local description="$3" | |
echo -e "${BLUE}Processing $description files...${NC}" | |
# Find all unique years for this pattern | |
local years | |
if [[ "$prefix" == "" ]]; then | |
# For older format files without prefix: YYMMDD-HHMMSS-*.syx | |
# Extract YY and convert to 20YY | |
years=$(ls $pattern 2>/dev/null | sed -E 's/^([0-9]{2})[0-9]{4}-.*\.syx/20\1/' | sort -u) | |
else | |
# For newer format files with prefix: DIRNAME-YYMMDD-HHMMSS-*.syx | |
# Extract YY from YYMMDD and convert to 20YY | |
years=$(ls $pattern 2>/dev/null | sed -E 's/^[^-]+-([0-9]{2})[0-9]{4}-.*\.syx/20\1/' | sort -u) | |
fi | |
if [ -z "$years" ]; then | |
echo -e " ${YELLOW}No $description files found.${NC}" | |
return | |
fi | |
local count=0 | |
for year in $years; do | |
local files | |
local year_pattern | |
local yy="${year#20}" # Extract YY from 20YY | |
if [[ "$prefix" == "" ]]; then | |
# For older format: find files starting with YY | |
files=$(ls ${yy}[0-9][0-9][0-9][0-9]-*.syx 2>/dev/null || true) | |
else | |
# For newer format: find files with prefix-YY | |
files=$(ls ${prefix}${yy}[0-9][0-9][0-9][0-9]-*.syx 2>/dev/null || true) | |
fi | |
if [ -n "$files" ]; then | |
local zip_name="${year}.zip" | |
local file_count=$(echo $files | wc -w) | |
# Check if archive already exists | |
if [ -f "$zip_name" ]; then | |
local existing_count=$(unzip -l "$zip_name" 2>/dev/null | tail -1 | awk '{print $2}' || echo "0") | |
echo -e " ${BLUE}Adding to existing ${zip_name}${NC} (currently has $existing_count files)" | |
echo " Adding: $file_count file(s) from year $year" | |
else | |
echo -e " ${GREEN}Creating new ${zip_name}${NC}" | |
echo " Files: $file_count file(s) from year $year" | |
fi | |
# Add files to the zip file (creates new or adds to existing) | |
if zip -q "$zip_name" $files; then | |
if [ -f "$zip_name" ]; then | |
local final_count=$(unzip -l "$zip_name" 2>/dev/null | tail -1 | awk '{print $2}' || echo "unknown") | |
echo -e " ${GREEN}✓ Files added to archive successfully${NC} (archive now has $final_count files)" | |
else | |
echo -e " ${GREEN}✓ Files added to archive successfully${NC}" | |
fi | |
# Delete the original files | |
rm $files | |
echo -e " ${GREEN}✓ Original files deleted${NC}" | |
((count++)) | |
else | |
echo -e " ${RED}✗ Failed to add files to archive${NC}" | |
fi | |
fi | |
done | |
echo -e " ${GREEN}Processed $count year(s)${NC}" | |
echo | |
} | |
# Safety check: Ask user for confirmation | |
echo -e "${YELLOW}WARNING: This script will DELETE the original .syx files after zipping them!${NC}" | |
echo -e "${YELLOW}Files will be grouped by year and added to YYYY.zip archives.${NC}" | |
echo | |
read -p "Do you want to continue? (y/N): " -r | |
if [[ ! $REPLY =~ ^[Yy]$ ]]; then | |
echo -e "${RED}Operation cancelled.${NC}" | |
exit 1 | |
fi | |
echo | |
# Count total files before processing | |
total_files=$(ls *.syx 2>/dev/null | wc -l) | |
echo -e "${BLUE}Found $total_files .syx files total${NC}" | |
echo | |
# Process newer format files: <DEVICE_PREFIX>-YYMMDD-HHMMSS-*.syx | |
process_yearly_files "${DEVICE_PREFIX}-[0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9]-*.syx" "${DEVICE_PREFIX}-" "newer format (${DEVICE_PREFIX}-YYMMDD-HHMMSS)" | |
# Process older format files: YYMMDD-HHMMSS-*.syx (without device prefix) | |
process_yearly_files "[0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9]-*.syx" "" "older format (YYMMDD-HHMMSS)" | |
# Count remaining files | |
if ls *.syx >/dev/null 2>&1; then | |
remaining_files=$(ls *.syx | wc -l) | |
else | |
remaining_files=0 | |
fi | |
processed_files=$((total_files - remaining_files)) | |
echo -e "${GREEN}✓ Processing complete!${NC}" | |
echo -e " Files processed: ${GREEN}$processed_files${NC}" | |
echo -e " Files remaining: ${YELLOW}$remaining_files${NC}" | |
if [ "$remaining_files" -gt 0 ]; then | |
echo | |
echo -e "${YELLOW}Remaining files (didn't match expected patterns):${NC}" | |
ls *.syx 2>/dev/null || true | |
fi | |
echo | |
echo -e "${BLUE}Created/updated yearly archives:${NC}" | |
if ls *.zip >/dev/null 2>&1; then | |
for zipfile in *.zip; do | |
if [[ "$zipfile" =~ ^[0-9]{4}\.zip$ ]]; then | |
file_count=$(unzip -l "$zipfile" 2>/dev/null | tail -1 | awk '{print $2}') | |
echo " ${GREEN}$zipfile${NC} (${file_count} files)" | |
fi | |
done | |
else | |
echo -e "${YELLOW}No yearly archives created.${NC}" | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment