mirror of
https://github.com/Dispatcharr/Dispatcharr.git
synced 2026-01-23 02:35:14 +00:00
69 lines
2.4 KiB
Python
69 lines
2.4 KiB
Python
import os
|
||
import socket
|
||
import threading
|
||
import time
|
||
import gevent # Add this import
|
||
from django.conf import settings
|
||
|
||
# SSDP Multicast Address and Port
|
||
SSDP_MULTICAST = "239.255.255.250"
|
||
SSDP_PORT = 1900
|
||
|
||
DEVICE_TYPE = "urn:schemas-upnp-org:device:MediaServer:1"
|
||
SERVER_PORT = 8000
|
||
|
||
def get_host_ip():
|
||
try:
|
||
# This relies on "host.docker.internal" being mapped to the host’s gateway IP.
|
||
return socket.gethostbyname("host.docker.internal")
|
||
except Exception:
|
||
return "127.0.0.1"
|
||
|
||
def ssdp_response(addr, host_ip):
|
||
response = (
|
||
f"HTTP/1.1 200 OK\r\n"
|
||
f"CACHE-CONTROL: max-age=1800\r\n"
|
||
f"EXT:\r\n"
|
||
f"LOCATION: http://{host_ip}:{SERVER_PORT}/hdhr/device.xml\r\n"
|
||
f"SERVER: Dispatcharr/1.0 UPnP/1.0 HDHomeRun/1.0\r\n"
|
||
f"ST: {DEVICE_TYPE}\r\n"
|
||
f"USN: uuid:device1-1::{DEVICE_TYPE}\r\n"
|
||
f"\r\n"
|
||
)
|
||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
|
||
sock.sendto(response.encode("utf-8"), addr)
|
||
sock.close()
|
||
|
||
def ssdp_listener(host_ip):
|
||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
|
||
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||
sock.bind((SSDP_MULTICAST, SSDP_PORT))
|
||
while True:
|
||
data, addr = sock.recvfrom(1024)
|
||
if b"M-SEARCH" in data and DEVICE_TYPE.encode("utf-8") in data:
|
||
print(f"Received M-SEARCH from {addr}")
|
||
ssdp_response(addr, host_ip)
|
||
|
||
def ssdp_broadcaster(host_ip):
|
||
notify = (
|
||
f"NOTIFY * HTTP/1.1\r\n"
|
||
f"HOST: {SSDP_MULTICAST}:{SSDP_PORT}\r\n"
|
||
f"CACHE-CONTROL: max-age=1800\r\n"
|
||
f"LOCATION: http://{host_ip}:{SERVER_PORT}/hdhr/device.xml\r\n"
|
||
f"SERVER: Dispatcharr/1.0 UPnP/1.0 HDHomeRun/1.0\r\n"
|
||
f"NT: {DEVICE_TYPE}\r\n"
|
||
f"NTS: ssdp:alive\r\n"
|
||
f"USN: uuid:device1-1::{DEVICE_TYPE}\r\n"
|
||
f"\r\n"
|
||
)
|
||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
|
||
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
|
||
while True:
|
||
sock.sendto(notify.encode("utf-8"), (SSDP_MULTICAST, SSDP_PORT))
|
||
gevent.sleep(30) # Replace time.sleep with gevent.sleep
|
||
|
||
def start_ssdp():
|
||
host_ip = get_host_ip()
|
||
threading.Thread(target=ssdp_listener, args=(host_ip,), daemon=True).start()
|
||
threading.Thread(target=ssdp_broadcaster, args=(host_ip,), daemon=True).start()
|
||
print(f"SSDP services started on {host_ip}.")
|