A robust solution for automatically processing downloaded media files from Transmission, organizing them with FileBot, and triggering Plex library updates. This project evolved from a simple cleanup script into a comprehensive media management solution.
- macOS (tested on Monterey and later)
- Plex Media Server (running locally)
- FileBot (licensed version)
- Transmission (for downloading)
- Homebrew (for installing dependencies)
- Command line tools:
- yq (
brew install yq) - xmlstarlet (
brew install xmlstarlet) - curl (usually pre-installed on macOS)
- yq (
Note: The installation wizard (
install.sh) can automatically install missing dependencies with your permission.
-
Clone this repository or download the scripts to your preferred location:
git clone <repository-url> cd transmission-filebot
-
Run the installation wizard:
./install.sh
The wizard will:
- Check for required dependencies and offer to install them
- Validate your Plex server is reachable
- Guide you through obtaining a Plex authentication token
- Display your Plex library sections to help choose the media path
- Generate a complete configuration file at
~/.config/transmission-done/config.yml - Create a symlink at
~/.local/bin/transmission-done - Back up any existing configuration with a timestamp
That's it! The script is now installed and ready to use.
The setup wizard creates ~/.config/transmission-done/config.yml automatically. If you need to modify it later:
paths:
default_home: /Users/yourusername
plex:
server: http://localhost:32400
token: your_plex_token_here
media_path: /path/to/your/plex/media
logging:
file: .filebot/logs/transmission-processing.log
max_size: 10485760 # 10MB in bytesConfigure Transmission to run the script automatically:
- Open Transmission
- Go to Preferences (⌘,)
- Navigate to the "Downloading" tab
- Check "Run script when download completes"
- Enter:
~/.local/bin/transmission-done(or the full path shown during installation)
When Transmission completes a download:
- The script validates the environment and configuration
- Cleans up unwanted files (NFO, TXT, EXE)
- Uses FileBot to:
- Identify the media (TV show or movie)
- Rename files according to Plex conventions
- Move files to the appropriate Plex library folder
- Download artwork and metadata
- Import subtitles
- Triggers a Plex library scan
- Logs all actions for troubleshooting
The script supports both automated (Transmission) and manual invocation modes.
Double-click process-media.command or run from terminal:
./process-media.commandThe script will:
- Present a native macOS folder picker dialog
- Process all media files in the selected folder
- Show preview and ask for confirmation
- Display macOS notifications on completion
Create MediaProcessor.app using Automator (see CREATE_AUTOMATOR_APP.md):
- Drag a folder containing media files onto the app
- The app processes the files automatically
- Notifications indicate success or failure
- Safety Checks: Verifies files are complete (not being downloaded)
- Preview: Shows what changes will be made before processing
- Confirmation: Asks for approval before moving files
- Notifications: macOS notifications with success/failure sounds
- No Transmission Required: Works independently of Transmission
When Transmission runs the script, it does so with a limited environment that differs from your regular shell environment. The script receives:
-
From Transmission:
TR_TORRENT_DIR: Directory containing the downloaded filesTR_TORRENT_NAME: Name of the downloaded torrentTR_APP_VERSION: Transmission versionTR_TIME_LOCALTIME: Local time of completionTR_TORRENT_HASH: Torrent hashTR_TORRENT_ID: Internal Transmission torrent ID
-
System Environment:
- Limited
PATH(usually just/usr/bin:/bin:/usr/sbin:/sbin) - No user environment variables (like those set in
.zshrcor.bash_profile) - No
HOMEvariable by default
- Limited
This is why the script:
- Explicitly sets
PATHto include/usr/local/bin - Uses a configurable
default_homein config.yml - Sources all paths from the config file rather than environment variables
If you need to debug environment issues:
# Add this near the start of the script
env > /tmp/transmission-env.log-
Script not running after download
- Check Transmission's script path setting
- Verify script permissions (
chmod +x) - Check the log file for errors
-
FileBot errors
- Ensure FileBot is properly licensed
- Verify FileBot is in your PATH
- Check if the target media directory exists and is writable
-
Plex not updating
- Verify your Plex token is correct
- Ensure Plex server is running
- Check server URL in config.yml
- Look for connection errors in the logs
-
Check the logs:
tail -f ~/.filebot/logs/transmission-processing.log -
Run the test suite:
./run_tests.sh
-
Verify Plex connectivity:
curl -H "X-Plex-Token: your_token" http://localhost:32400/identity
This project uses BATS (Bash Automated Testing System) for comprehensive testing.
Install BATS:
brew install bats-coreRun all tests:
./run_tests.shRun only unit tests:
bats test/unit/*.batsRun only integration tests:
bats test/integration/*.batsRun a specific test file:
bats test/unit/test_mode_detection.batsRun tests with verbose output:
bats -t test/unit/test_mode_detection.batsTest individual functions in isolation:
test_mode_detection.bats- Invocation mode detection (automated vs manual)test_type_detection.bats- Media type heuristics (TV vs movie)test_plex_api.bats- Plex API functions and library scanstest_filebot.bats- FileBot processing and fallback chainstest_error_logging.bats- Error analysis and reportingtest_file_safety.bats- File readiness and safety checks
Test complete end-to-end workflows:
test_tv_workflow.bats- Complete TV show processing workflowtest_movie_workflow.bats- Complete movie processing workflowtest_manual_mode.bats- Manual invocation mode (user-initiated)
- 110 comprehensive tests covering all major functionality
- 63 unit tests verify individual components in isolation
- 47 integration tests verify complete end-to-end workflows
- All tests run in TEST_MODE to avoid side effects
- Comprehensive coverage of error conditions and edge cases
- Mock implementations for FileBot and Plex API calls
- Test helpers for common assertions and setup
Tests follow BATS conventions:
@test "description of what is being tested" {
# Setup
export TEST_MODE=true
local test_dir="${TEST_TEMP_DIR}/test"
mkdir -p "${test_dir}"
# Execute
run function_to_test "${test_dir}"
# Assert
assert_success
assert_equal "expected" "${output}"
}See existing tests in test/unit/ and test/integration/ for more examples.
This project began as a simple "done-cleanup" script that removed unwanted files after Transmission downloads completed. Key evolution points:
- Initial Version: Basic cleanup of NFO, TXT, and EXE files
- FileBot Integration: Added automated media organization and renaming
- Plex Integration: Implemented automatic library updates
- Robust Error Handling: Added retry logic and comprehensive logging
- Configuration Management: Moved from hardcoded values to YAML configuration
- Test Suite (2026-01): Comprehensive BATS test infrastructure with 110 tests
- 63 unit tests for individual functions
- 47 integration tests for complete workflows
- Continuous integration with GitHub Actions
- Unified Installer (2026-01): One-command installation with
install.sh- Automatic dependency installation with user consent
- Plex server validation and token configuration
- Complete config file generation
- Library introspection with proper XML parsing
- Automatic symlink creation to
~/.local/bin
The current version is a comprehensive media automation solution with proper error handling, logging, configuration management, and extensive testing capabilities.
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
Please ensure tests pass before submitting: ./run_tests.sh
MIT License - See LICENSE file for details