Skip to content
Merged

Ui2 #47

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 83 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand All @@ -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

Expand Down Expand Up @@ -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.

<table>
<tr>
<td colspan="2">
<img src="https://github.com/user-attachments/assets/37c052cb-df00-4d61-aaa2-be8c0dd3c10e" width="100%"/>
<p align="center"><em>Demo Logger UI</em></p>
<td colspan="2">
<img width="100%" alt="image" src="https://github.com/user-attachments/assets/a076ea7e-9a7a-4e9b-a631-fa672068851d" />
<p align="center"><em>Logger UI</em></p>
</td>
</tr>
</table>
Expand All @@ -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

Expand All @@ -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:

<table>
<tr>
<td colspan="2">
<img width="930" alt="image" src="https://github.com/user-attachments/assets/19aa9f3c-7641-4b82-8867-22ca2e47536b" />
<p align="center"><em>Settings UI</em></p>
</td>
</tr>
</table>

- **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

Expand All @@ -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
Expand All @@ -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" \
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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" \
Expand Down Expand Up @@ -415,31 +478,38 @@ 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

- **API Key Issues**: Check that your API key is correct in Sonarr settings
- **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

---

Expand Down
29 changes: 21 additions & 8 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"""
Expand Down
27 changes: 21 additions & 6 deletions web_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down