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
82 lines
3.0 KiB
Python
82 lines
3.0 KiB
Python
#!/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() |