diff --git a/README.md b/README.md
index fdd360ac..6a66abf9 100644
--- a/README.md
+++ b/README.md
@@ -22,6 +22,7 @@ Visit: https://github.com/plexguide/Huntarr-Sonarr/releases/
- [How It Works](#how-it-works)
- [Configuration Options](#configuration-options)
- [Web Interface](#web-interface)
+- [Persistent Storage](#persistent-storage)
- [Installation Methods](#installation-methods)
- [Docker Run](#docker-run)
- [Docker Compose](#docker-compose)
@@ -60,9 +61,11 @@ My 12-year-old daughter is passionate about singing, dancing, and exploring STEM
- 🔁 **State Tracking**: Remembers which shows and episodes have been processed to avoid duplicate searches
- ⚙️ **Configurable Reset Timer**: Automatically resets search history after a configurable period
- 📦 **Modular Design**: Modern codebase with separated concerns for easier maintenance
-- 🌐 **Web Interface**: Real-time log viewer with day/night mode
+- 🌐 **Web Interface**: Real-time log viewer with day/night mode and settings management
- 🔮 **Future Episode Skipping**: Skip processing episodes with future air dates
- 💾 **Reduced Disk Activity**: Option to skip series refresh before processing
+- 💿 **Persistent Configuration**: All settings are saved to disk and persist across container restarts
+- 📝 **Stateful Operation**: Processed state is now permanently saved between restarts
## Indexers Approving of Huntarr:
* https://ninjacentral.co.za
@@ -82,6 +85,7 @@ My 12-year-old daughter is passionate about singing, dancing, and exploring STEM
- Skips episodes with future air dates (configurable)
4. **State Management**:
- Tracks which shows and episodes have been processed
+ - Stores this information persistently in the `/config` volume
- Automatically resets this tracking after a configurable time period
5. **Repeat Cycle**: Waits for a configurable period before starting the next cycle
@@ -197,15 +201,16 @@ The following environment variables can be configured:
- The minimum number of items in the download queue before a new hunt is initiated. For example if set to `5` then a new hunt will only start when there are 5 or less items marked as `downloading` in the queue.
- This helps prevent overwhelming the queue with too many download requests at once and avoids creating a massive backlog of downloads.
- Set to `-1` to disable this check.
-
+
## Web Interface
-Huntarr-Sonarr includes a real-time log viewer web interface that allows you to monitor its operation directly from your browser.
+Huntarr-Sonarr includes a real-time log viewer and settings management web interface that allows you to monitor and configure its operation directly from your browser.
+
-
-
- Demo Logger UI
+ |
+
+ Logger UI
|
@@ -217,6 +222,8 @@ Huntarr-Sonarr includes a real-time log viewer web interface that allows you to
- **Color-coded Log Entries**: Different log levels are displayed in different colors
- **Auto-scrolling**: Automatically scrolls to the latest log entries
- **Connection Status**: Shows whether the connection to the log stream is active
+- **Settings Management**: Configure Huntarr directly from the web interface
+- **Persistent Configuration**: All settings are saved to disk and persist across container restarts
### How to Access
@@ -226,11 +233,34 @@ The web interface is available on port 8988. Simply navigate to:
http://YOUR_SERVER_IP:8988
```
-Or if you're accessing it locally:
+The URL will be displayed in the logs when Huntarr starts, using the same hostname you configured for your API_URL.
-```
-http://localhost:8988
-```
+### Web UI Settings
+
+The web interface allows you to configure all of Huntarr's settings without having to restart the container:
+
+
+
+
+
+ Settings UI
+ |
+
+
+
+- **Hunt Settings**
+ - **Hunt Missing Shows**: Maximum number of missing shows to process per cycle
+ - **Hunt Upgrade Episodes**: Maximum number of episodes to upgrade per cycle
+
+- **Timing Settings**
+ - **Sleep Duration**: Time to wait between cycles (in seconds)
+ - **State Reset Interval**: Hours after which processed items will be forgotten
+
+- **Processing Options**
+ - **Monitored Only**: Only process monitored shows and episodes
+ - **Random Selection**: Select shows and episodes randomly instead of sequentially
+ - **Skip Future Episodes**: Skip processing episodes with future air dates
+ - **Skip Series Refresh**: Skip refreshing series metadata before processing
### Port Configuration Explained
@@ -253,6 +283,35 @@ The web interface can be enabled or disabled using the `ENABLE_WEB_UI` environme
If you disable the web interface, you don't need to expose the port in your Docker configuration.
+## Persistent Storage
+
+Huntarr-Sonarr now stores all its configuration and state information in persistent storage, ensuring your settings and processed state are maintained across container restarts and updates.
+
+### Storage Locations
+
+The following directories are used for persistent storage:
+
+- `/config/settings/` - Contains configuration settings (huntarr.json)
+- `/config/stateful/` - Contains the state tracking files for processed shows and episodes
+
+### Data Persistence
+
+All data in these directories is maintained across container restarts. This means:
+
+1. Your settings configured via the web UI will be preserved
+2. The list of shows and episodes that have already been processed will be maintained
+3. After a container update or restart, Huntarr will continue from where it left off
+
+### Volume Mapping
+
+To ensure data persistence, make sure you map the `/config` directory to a persistent volume on your host system:
+
+```bash
+-v /mnt/user/appdata/huntarr-sonarr:/config
+```
+
+This mapping is included in all of the installation examples below.
+
---
## Installation Methods
@@ -265,6 +324,7 @@ The simplest way to run Huntarr is via Docker:
docker run -d --name huntarr-sonarr \
--restart always \
-p 8988:8988 \
+ -v /mnt/user/appdata/huntarr-sonarr:/config \
-e API_KEY="your-api-key" \
-e API_URL="http://your-sonarr-address:8989" \
-e API_TIMEOUT="60" \
@@ -304,6 +364,8 @@ services:
restart: always
ports:
- "8988:8988"
+ volumes:
+ - /mnt/user/appdata/huntarr-sonarr:/config
environment:
API_KEY: "your-api-key"
API_URL: "http://your-sonarr-address:8989"
@@ -339,6 +401,7 @@ Run this from Command Line in Unraid:
docker run -d --name huntarr-sonarr \
--restart always \
-p 8988:8988 \
+ -v /mnt/user/appdata/huntarr-sonarr:/config \
-e API_KEY="your-api-key" \
-e API_URL="http://your-sonarr-address:8989" \
-e API_TIMEOUT="60" \
@@ -415,20 +478,25 @@ sudo systemctl start huntarr
- **Real-time Monitoring**: Use the web interface to see what's happening at any time
- **Disk Usage Optimization**: Skip refreshing metadata to reduce disk wear and tear
- **Efficient Searching**: Skip processing episodes with future air dates to save resources
+- **Persistent Configuration**: Save your settings once and have them persist through updates
+- **Stateful Operation**: Maintain processing state across container restarts and updates
## Tips
- **First-Time Use**: Start with default settings to ensure it works with your setup
+- **Web Interface**: Use the web interface to adjust settings without restarting the container
- **Adjusting Speed**: Lower the `SLEEP_DURATION` to search more frequently (be careful with indexer limits)
- **Batch Size Control**: Adjust `HUNT_MISSING_SHOWS` and `HUNT_UPGRADE_EPISODES` based on your indexer's rate limits
- **Monitored Status**: Set `MONITORED_ONLY=false` if you want to download all missing episodes regardless of monitored status
- **System Resources**: The script uses minimal resources and can run continuously on even low-powered systems
-- **Web Interface**: Use the web interface to monitor progress instead of checking Docker logs
- **Port Conflicts**: If port 8988 is already in use, map to a different host port (e.g., `-p 9000:8988`)
- **Disable Web UI**: Set `ENABLE_WEB_UI=false` if you don't need the interface to save resources
- **Debugging Issues**: Enable `DEBUG_MODE=true` temporarily to see detailed logs when troubleshooting
- **Hard Drive Saving**: Enable `SKIP_SERIES_REFRESH=true` to reduce disk activity
- **Search Efficiency**: Keep `SKIP_FUTURE_EPISODES=true` to avoid searching for unavailable content
+- **Persistent Storage**: Make sure to map the `/config` volume to preserve settings and state
+- **Dark Mode**: Toggle between light and dark themes in the web interface for comfortable viewing
+- **Settings Persistence**: Any settings changed in the web UI are saved immediately and permanently
## Troubleshooting
@@ -436,10 +504,12 @@ sudo systemctl start huntarr
- **Connection Problems**: Ensure the Sonarr URL is accessible from where you're running the script
- **Command Failures**: If search commands fail, try using the Sonarr UI to verify what commands are available in your version
- **Web Interface Not Loading**: Make sure port 8988 is exposed in your Docker configuration and not blocked by a firewall
-- **Logs**: Check the container logs with `docker logs huntarr-sonarr` if running in Docker
+- **Logs**: Check the container logs with `docker logs huntarr-sonarr` if running in Docker, or use the web interface
- **Debug Mode**: Enable `DEBUG_MODE=true` to see detailed API responses and process flow
-- **State Files**: The script stores state in `/tmp/huntarr-state/` - if something seems stuck, you can try deleting these files
+- **Settings Not Persisting**: Verify your volume mount for `/config` is configured correctly
+- **State Files**: The script stores state in `/config/stateful/` - if something seems stuck, you can try deleting these files
- **Excessive Disk Activity**: If you notice high disk usage, try enabling `SKIP_SERIES_REFRESH=true`
+- **Web UI URL Issues**: The web interface URL shown in logs is now derived from your API_URL setting
---
diff --git a/main.py b/main.py
index 4f94f183..739898e5 100644
--- a/main.py
+++ b/main.py
@@ -16,15 +16,28 @@
from api import get_download_queue_size
def get_ip_address():
- """Get the host's IP address or hostname for display"""
+ """Get the host's IP address from API_URL for display"""
try:
- # Try to get the container's hostname
- hostname = socket.gethostname()
- # Try to get the container's IP
- ip = socket.gethostbyname(hostname)
- return ip
- except:
- return "YOUR_SERVER_IP"
+ from urllib.parse import urlparse
+ from config import API_URL
+
+ # Extract the hostname/IP from the API_URL
+ parsed_url = urlparse(API_URL)
+ hostname = parsed_url.netloc
+
+ # Remove port if present
+ if ':' in hostname:
+ hostname = hostname.split(':')[0]
+
+ return hostname
+ except Exception as e:
+ # Fallback to the current method if there's an issue
+ try:
+ hostname = socket.gethostname()
+ ip = socket.gethostbyname(hostname)
+ return ip
+ except:
+ return "YOUR_SERVER_IP"
def main_loop() -> None:
"""Main processing loop for Huntarr-Sonarr"""
diff --git a/web_server.py b/web_server.py
index 8e1c27d7..53663268 100644
--- a/web_server.py
+++ b/web_server.py
@@ -155,13 +155,28 @@ def update_theme():
return jsonify({"success": False, "message": str(e)}), 500
def get_ip_address():
- """Get the host's IP address or hostname for display"""
+ """Get the host's IP address from API_URL for display"""
try:
- hostname = socket.gethostname()
- ip = socket.gethostbyname(hostname)
- return ip
- except:
- return "localhost"
+ from urllib.parse import urlparse
+ from config import API_URL
+
+ # Extract the hostname/IP from the API_URL
+ parsed_url = urlparse(API_URL)
+ hostname = parsed_url.netloc
+
+ # Remove port if present
+ if ':' in hostname:
+ hostname = hostname.split(':')[0]
+
+ return hostname
+ except Exception as e:
+ # Fallback to the current method if there's an issue
+ try:
+ hostname = socket.gethostname()
+ ip = socket.gethostbyname(hostname)
+ return ip
+ except:
+ return "localhost"
if __name__ == "__main__":
# Create a basic log entry at startup