Add initial commit of new media management docker stack
Includes transmission, gluetun, sonarr, radarr stacks Includes framework for adding plex, tautulli, prowlarr, overseerr, requestrr, and trash guides sync stacks Includes port-watcher docker container that monitors gluetun port forwarding file and sets transmission peer_port automatically
This commit is contained in:
82
media-dude/torrentarr/port-watcher/port-watcher.py
Normal file
82
media-dude/torrentarr/port-watcher/port-watcher.py
Normal file
@@ -0,0 +1,82 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import time
|
||||
import logging
|
||||
from transmission_rpc import Client
|
||||
from watchdog.observers import Observer
|
||||
from watchdog.events import FileSystemEventHandler
|
||||
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(message)s')
|
||||
logger = logging.getLogger()
|
||||
|
||||
PORT_FILE = os.getenv('PORT_FILE', '/watch/forwarded_port')
|
||||
TRANSMISSION_HOST = os.getenv('TRANSMISSION_HOST', 'gluetun')
|
||||
TRANSMISSION_PORT = os.getenv('TRANSMISSION_PORT', 9091)
|
||||
|
||||
class PortFileHandler(FileSystemEventHandler):
|
||||
def __init__(self):
|
||||
self.last_port = None
|
||||
self.transmission_client = Client(host=TRANSMISSION_HOST, port=TRANSMISSION_PORT)
|
||||
self.check_port_file() # Initial check
|
||||
|
||||
def on_modified(self, event):
|
||||
if not event.is_directory and event.src_path == PORT_FILE:
|
||||
self.check_port_file()
|
||||
|
||||
def check_port_file(self):
|
||||
try:
|
||||
if not os.path.exists(PORT_FILE):
|
||||
logger.info(f"Port file not found: {PORT_FILE}")
|
||||
return
|
||||
|
||||
with open(PORT_FILE, 'r') as f:
|
||||
port = f.read().strip()
|
||||
|
||||
if port != self.last_port and port.isdigit():
|
||||
self.last_port = port
|
||||
logger.info(f"Port forwarding changed to: {port}")
|
||||
self.update_transmission(port)
|
||||
except Exception as e:
|
||||
logger.error(f"Error checking port file: {e}")
|
||||
|
||||
def update_transmission(self, port):
|
||||
max_attempts = 5
|
||||
attempt = 1
|
||||
delay = 5 # seconds between retry attempts
|
||||
|
||||
while attempt <= max_attempts:
|
||||
logger.info(f"Attempt {attempt}/{max_attempts}: Setting Transmission peer_port to {port}")
|
||||
try:
|
||||
self.transmission_client.set_session(peer_port=int(port))
|
||||
logger.info(f"Successfully updated Transmission peer_port to {port}")
|
||||
logger.info(f"Testing Transmission peer port...")
|
||||
if self.transmission_client.port_test():
|
||||
logger.info("Transmission peer port is open")
|
||||
else:
|
||||
logger.warning("Transmission peer port does not appear to be open")
|
||||
return
|
||||
except Exception as e:
|
||||
logger.warning(f"Attempt {attempt}/{max_attempts} failed: {e}")
|
||||
if attempt < max_attempts:
|
||||
logger.info(f"Retrying in {delay} seconds...")
|
||||
time.sleep(delay)
|
||||
attempt += 1
|
||||
|
||||
logger.error(f"Failed to update Transmission peer_port after {max_attempts} attempts")
|
||||
|
||||
if __name__ == "__main__":
|
||||
path = os.path.dirname(PORT_FILE)
|
||||
logger.info(f"Starting port-watcher monitoring {PORT_FILE}")
|
||||
|
||||
event_handler = PortFileHandler()
|
||||
observer = Observer()
|
||||
observer.schedule(event_handler, path, recursive=False)
|
||||
observer.start()
|
||||
|
||||
try:
|
||||
while True:
|
||||
time.sleep(1)
|
||||
except KeyboardInterrupt:
|
||||
observer.stop()
|
||||
observer.join()
|
||||
Reference in New Issue
Block a user