diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..9cf1062 --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..cefa3db --- /dev/null +++ b/README.md @@ -0,0 +1,176 @@ +# renamarr + +A rolling rename utility for Sonarr and Radarr that safely triggers filename updates with staggered delays. Useful for avoiding API rate limits or filesystem locks when renaming large numbers of episodes/movies. + +## Features + +- **Staggered Renames**: Configurable delays between rename operations to avoid overwhelming your server +- **Progress Tracking**: Automatically tracks completed renames across runs—re-runs skip already-processed files +- **Sonarr & Radarr Support**: Works with both TV series (Sonarr) and movies (Radarr) +- **Selective Renaming**: Filter by season number to rename specific seasons only +- **Cross-Platform Path Mapping**: Converts between local and server paths (Windows ↔ Linux) +- **Detailed Logging**: JSON-formatted logs with timestamps, file paths, and episode details +- **Smart Caching**: Caches series/movie metadata to minimize API calls + +## Requirements + +- Python 3.7+ +- Sonarr v3+ and/or Radarr with API access +- Network access to your Sonarr/Radarr instance + +## Installation + +1. Clone or download this repository +2. Install dependencies: + ```bash + pip install requests + ``` + +3. Configure `config.xml` with your Sonarr/Radarr details: + ```xml + + + + + + + + + + http://10.0.0.10:8989 + your_sonarr_api_key_here + + + http://10.0.0.10:7878 + your_radarr_api_key_here + + + + ``` + +## Usage + +### Basic Usage + +Rename all episodes in a series: +```bash +python main.py "P:\tv\Breaking Bad" +``` + +### With Options + +Rename only a specific season: +```bash +python main.py "P:\tv\Breaking Bad" -s 5 +``` + +Customize wait time between renames (in seconds): +```bash +python main.py "P:\tv\Breaking Bad" -w 60 +``` + +Combine options: +```bash +python main.py "P:\tv\Supernatural" --season 15 --wait 180 +``` + +### Interactive Mode + +If you run without a folder argument, the script will prompt you: +```bash +python main.py +Enter series folder path: P:\tv\Breaking Bad +``` + +## Configuration + +### config.xml + +**Path Mappings**: Map local paths to server paths. This is essential if: +- Your local machine uses Windows (`P:\tv`) but Sonarr runs on Linux (`/mnt/plex/tv`) +- You provide a server path to the script and need it converted to local for verification + +**Services**: Add your Sonarr/Radarr URLs and API keys. You can find API keys in: +- Sonarr: Settings → General → API Key +- Radarr: Settings → General → API Key + +## How It Works + +1. **Initialization**: Loads Sonarr/Radarr caches to find your series/movie +2. **Filtering**: Identifies episodes/movies with files, optionally filters by season +3. **Progress Check**: Loads progress tracking to skip already-renamed files +4. **Rolling Renames**: Triggers one rename at a time with configurable delays +5. **Progress Saving**: Updates progress after each rename to resume if interrupted + +Progress is stored in `logs/rolling_rename_progress.json` and includes: +- Series/movie ID and title +- Count of completed vs total episodes +- Timestamp of each rename + +## Output + +Logs are stored in `logs/rolling_rename.log` with detailed JSON entries: +```json +{"timestamp": "2026-01-01T17:47:04Z", "level": "INFO", "message": "[1/12] Breaking Bad - S05E01 - Fifty-One", "module": "main", "funcName": "rolling_rename_series", "line": 169} +``` + +## Troubleshooting + +### "Folder not found" error +- Verify the path is correct and accessible +- If using a server path (e.g., `/mnt/plex/tv`), ensure `path_mappings` in config.xml is set up to convert it + +### "Series not found in Sonarr/Radarr" +- Verify the series/movie exists in your Sonarr/Radarr library +- Check that API keys and URLs in config.xml are correct +- Ensure the folder path matches what Sonarr/Radarr has configured + +### API Key or Connection Issues +- Verify Sonarr/Radarr is running and accessible at the configured URL +- Check API key is correct (copy directly from settings, avoid typos) +- Verify firewall/network allows connection to Sonarr/Radarr + +### Re-running doesn't rename remaining files +- Check `logs/rolling_rename_progress.json` to see what's already completed +- You can delete this file to reset progress and re-rename everything + +## Project Structure + +``` +renamarr/ +├── main.py # Main entry point +├── config.xml # Configuration (Sonarr/Radarr URLs, API keys, path mappings) +├── .gitignore # Git ignore rules +├── README.md # This file +├── core/ +│ ├── config_helper.py # Loads and parses config.xml +│ ├── sonarr_radarr_helper.py # Sonarr/Radarr API communication +│ └── logger_helper.py # Structured JSON logging setup +├── cache/ +│ ├── sonarr_cache.json # Cached Sonarr series data +│ ├── radarr_cache.json # Cached Radarr movies data +│ └── temp_episodes.json # Temporary episode cache for current operation +└── logs/ + ├── rolling_rename.log # Main log file (JSON formatted) + └── rolling_rename_progress.json # Progress tracking across runs +``` + +## Tips + +- **First Run**: The first run is slow because it fetches and caches all series/movies from Sonarr/Radarr. Subsequent runs are faster. +- **Large Libraries**: For large libraries, caches can take 30+ seconds to load. This is normal. +- **Safe to Interrupt**: If you interrupt the script (Ctrl+C), progress is saved. Just run again to resume. +- **Batch Operations**: Use a loop or scheduler to rename multiple series: + ```bash + python main.py "P:\tv\Show 1" -w 30 + python main.py "P:\tv\Show 2" -w 30 + python main.py "P:\tv\Show 3" -w 30 + ``` + +## License + +MIT License - See LICENSE file for details + +## Support + +For issues or questions, check the logs in `logs/rolling_rename.log` for detailed error messages.