\n")
+
+ for line in page_elements["end"]:
+ fakefile.write(line + "\n")
+
+ return fakefile.getvalue()
diff --git a/fHDHR/api/hub/pages/diagnostics_html.py b/fHDHR/api/hub/pages/diagnostics_html.py
index 320af20..63ddcb2 100644
--- a/fHDHR/api/hub/pages/diagnostics_html.py
+++ b/fHDHR/api/hub/pages/diagnostics_html.py
@@ -13,8 +13,9 @@ class Diagnostics_HTML():
if not self.diagnostics_html or force_update:
fakefile = StringIO()
+ page_elements = self.page_elements.get()
- for line in self.page_elements["top"]:
+ for line in page_elements["top"]:
fakefile.write(line + "\n")
# a list of 2 part lists containing button information
@@ -24,7 +25,8 @@ class Diagnostics_HTML():
["device.xml", "device.xml"],
["discover.json", "discover.json"],
["lineup.json", "lineup.json"],
- ["lineup_status.json", "lineup_status.json"]
+ ["lineup_status.json", "lineup_status.json"],
+ ["cluster.json", "cluster.json"]
]
for button_item in button_list:
@@ -35,7 +37,7 @@ class Diagnostics_HTML():
fakefile.write("\n")
fakefile.write("\n")
- for line in self.page_elements["end"]:
+ for line in page_elements["end"]:
fakefile.write(line + "\n")
self.diagnostics_html = fakefile.getvalue()
diff --git a/fHDHR/api/hub/pages/index_html.py b/fHDHR/api/hub/pages/index_html.py
index 95e0672..c83e294 100644
--- a/fHDHR/api/hub/pages/index_html.py
+++ b/fHDHR/api/hub/pages/index_html.py
@@ -11,8 +11,9 @@ class Index_HTML():
def get_index_html(self, base_url, force_update=False):
fakefile = StringIO()
+ page_elements = self.page_elements.get()
- for line in self.page_elements["top"]:
+ for line in page_elements["top"]:
fakefile.write(line + "\n")
fakefile.write("
fHDHR Status
")
@@ -43,7 +44,7 @@ class Index_HTML():
fakefile.write("
%s
\n" % (guts[1]))
fakefile.write(" \n")
- for line in self.page_elements["end"]:
+ for line in page_elements["end"]:
fakefile.write(line + "\n")
return fakefile.getvalue()
diff --git a/fHDHR/api/hub/pages/origin_html.py b/fHDHR/api/hub/pages/origin_html.py
index d6e8021..904ea96 100644
--- a/fHDHR/api/hub/pages/origin_html.py
+++ b/fHDHR/api/hub/pages/origin_html.py
@@ -13,8 +13,9 @@ class Origin_HTML():
servicename = str(self.config.dict["main"]["servicename"])
fakefile = StringIO()
+ page_elements = self.page_elements.get()
- for line in self.page_elements["top"]:
+ for line in page_elements["top"]:
fakefile.write(line + "\n")
fakefile.write("
%s Status
" % (servicename))
@@ -33,7 +34,7 @@ class Origin_HTML():
fakefile.write("
%s
\n" % (str(origin_status_dict[key])))
fakefile.write(" \n")
- for line in self.page_elements["end"]:
+ for line in page_elements["end"]:
fakefile.write(line + "\n")
return fakefile.getvalue()
diff --git a/fHDHR/api/hub/pages/version_html.py b/fHDHR/api/hub/pages/version_html.py
index 1297ee6..f5e2e31 100644
--- a/fHDHR/api/hub/pages/version_html.py
+++ b/fHDHR/api/hub/pages/version_html.py
@@ -13,8 +13,9 @@ class Version_HTML():
def get_version_html(self, base_url, force_update=False):
fakefile = StringIO()
+ page_elements = self.page_elements.get()
- for line in self.page_elements["top"]:
+ for line in page_elements["top"]:
fakefile.write(line + "\n")
fakefile.write("
\n")
@@ -28,7 +29,7 @@ class Version_HTML():
fakefile.write("
%s
\n" % (str(fHDHR_VERSION)))
fakefile.write(" \n")
- for line in self.page_elements["end"]:
+ for line in page_elements["end"]:
fakefile.write(line + "\n")
return fakefile.getvalue()
diff --git a/fHDHR/cli/run.py b/fHDHR/cli/run.py
index 2c89856..4987991 100644
--- a/fHDHR/cli/run.py
+++ b/fHDHR/cli/run.py
@@ -10,7 +10,6 @@ import fHDHR.config
import fHDHR.origin
import fHDHR.api
-import fHDHR.ssdpserver
ERR_CODE = 1
ERR_CODE_NO_RESTART = 2
@@ -37,10 +36,6 @@ def get_configuration(args, script_dir):
def run(settings, origin):
- if settings.dict["fhdhr"]["discovery_address"]:
- ssdpServer = Process(target=fHDHR.ssdpserver.ssdpServerProcess, args=(settings,))
- ssdpServer.start()
-
fhdhrweb = Process(target=fHDHR.api.interface_start, args=(settings, origin))
fhdhrweb.start()
diff --git a/fHDHR/config/__init__.py b/fHDHR/config/__init__.py
index bfc25b9..502cdb1 100644
--- a/fHDHR/config/__init__.py
+++ b/fHDHR/config/__init__.py
@@ -137,6 +137,8 @@ class Config():
cache_dir = self.dict["filedir"]["cache_dir"]
self.dict["main"]["channel_numbers"] = pathlib.Path(cache_dir).joinpath("cnumbers.json")
+ self.dict["main"]["ssdp_detect"] = pathlib.Path(cache_dir).joinpath("ssdp_list.json")
+ self.dict["main"]["cluster"] = pathlib.Path(cache_dir).joinpath("cluster.json")
for epg_method in self.dict["main"]["valid_epg_methods"]:
if epg_method and epg_method != "None":
diff --git a/fHDHR/ssdpserver/__init__.py b/fHDHR/ssdpserver/__init__.py
deleted file mode 100644
index 728767b..0000000
--- a/fHDHR/ssdpserver/__init__.py
+++ /dev/null
@@ -1,242 +0,0 @@
-# Licensed under the MIT license
-# http://opensource.org/licenses/mit-license.php
-
-# Copyright 2005, Tim Potter
-# Copyright 2006 John-Mark Gurney
-# Copyright (C) 2006 Fluendo, S.A. (www.fluendo.com).
-# Copyright 2006,2007,2008,2009 Frank Scholz
-# Copyright 2016 Erwan Martin
-#
-# Implementation of a SSDP server.
-#
-
-import random
-import time
-import socket
-import logging
-from email.utils import formatdate
-from errno import ENOPROTOOPT
-
-SSDP_ADDR = '239.255.255.250'
-
-
-logger = logging.getLogger()
-
-
-# mostly from https://github.com/ZeWaren/python-upnp-ssdp-example
-def ssdpServerProcess(settings):
- ssdp = SSDPServer()
- ssdp.ssdp_port = 1900
- ssdp.register('local',
- 'uuid:' + settings.dict["main"]["uuid"] + '::upnp:rootdevice',
- 'upnp:rootdevice',
- 'http://' + settings.dict["fhdhr"]["discovery_address"] + ':' +
- str(settings.dict["fhdhr"]["port"]) + '/device.xml')
- print("SSDP server Started on port " + str(ssdp.ssdp_port) +
- " and broadcasting the availability of " + settings.dict["fhdhr"]["friendlyname"] +
- " at " 'http://' + settings.dict["fhdhr"]["discovery_address"] + ':' + str(settings.dict["fhdhr"]["port"]))
- try:
- ssdp.run()
- except KeyboardInterrupt:
- pass
-
-
-class SSDPServer:
- """A class implementing a SSDP server. The notify_received and
- searchReceived methods are called when the appropriate type of
- datagram is received by the server."""
- known = {}
-
- def __init__(self):
- self.sock = None
-
- def run(self):
- self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
- self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
- if hasattr(socket, "SO_REUSEPORT"):
- try:
- self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
- except socket.error as le:
- # RHEL6 defines SO_REUSEPORT but it doesn't work
- if le.errno == ENOPROTOOPT:
- pass
- else:
- raise
-
- addr = socket.inet_aton(SSDP_ADDR)
- interface = socket.inet_aton('0.0.0.0')
- cmd = socket.IP_ADD_MEMBERSHIP
- self.sock.setsockopt(socket.IPPROTO_IP, cmd, addr + interface)
- self.sock.bind(('0.0.0.0', self.ssdp_port))
- self.sock.settimeout(1)
-
- while True:
- try:
- data, addr = self.sock.recvfrom(1024)
- self.datagram_received(data, addr)
- except socket.timeout:
- continue
- self.shutdown()
-
- def shutdown(self):
- for st in self.known:
- if self.known[st]['MANIFESTATION'] == 'local':
- self.do_byebye(st)
-
- def datagram_received(self, data, host_port):
- """Handle a received multicast datagram."""
-
- (host, port) = host_port
-
- try:
- header, payload = data.decode().split('\r\n\r\n')[:2]
- except ValueError as err:
- logger.error(err)
- return
-
- lines = header.split('\r\n')
- cmd = lines[0].split(' ')
- lines = [x.replace(': ', ':', 1) for x in lines[1:]]
- lines = [x for x in lines if len(x) > 0]
-
- headers = [x.split(':', 1) for x in lines]
- headers = dict([(x[0].lower(), x[1]) for x in headers])
-
- logger.info('SSDP command %s %s - from %s:%d' % (cmd[0], cmd[1], host, port))
- logger.debug('with headers: {}.'.format(headers))
- if cmd[0] == 'M-SEARCH' and cmd[1] == '*':
- # SSDP discovery
- self.discovery_request(headers, (host, port))
- elif cmd[0] == 'NOTIFY' and cmd[1] == '*':
- # SSDP presence
- logger.debug('NOTIFY *')
- else:
- logger.warning('Unknown SSDP command %s %s' % (cmd[0], cmd[1]))
-
- def register(self, manifestation, usn, st, location, cache_control='max-age=1800', silent=False,
- host=None):
- """Register a service or device that this SSDP server will
- respond to."""
-
- logging.info('Registering %s (%s)' % (st, location))
-
- self.known[usn] = {}
- self.known[usn]['USN'] = usn
- self.known[usn]['LOCATION'] = location
- self.known[usn]['ST'] = st
- self.known[usn]['EXT'] = ''
- self.known[usn]['SERVER'] = "fHDHR Server"
- self.known[usn]['CACHE-CONTROL'] = cache_control
-
- self.known[usn]['MANIFESTATION'] = manifestation
- self.known[usn]['SILENT'] = silent
- self.known[usn]['HOST'] = host
- self.known[usn]['last-seen'] = time.time()
-
- if manifestation == 'local' and self.sock:
- self.do_notify(usn)
-
- def unregister(self, usn):
- logger.info("Un-registering %s" % usn)
- del self.known[usn]
-
- def is_known(self, usn):
- return usn in self.known
-
- def send_it(self, response, destination, delay, usn):
- logger.debug('send discovery response delayed by %ds for %s to %r' % (delay, usn, destination))
- try:
- self.sock.sendto(response.encode(), destination)
- except (AttributeError, socket.error) as msg:
- logger.warning("failure sending out byebye notification: %r" % msg)
-
- def discovery_request(self, headers, host_port):
- """Process a discovery request. The response must be sent to
- the address specified by (host, port)."""
-
- (host, port) = host_port
-
- logger.info('Discovery request from (%s,%d) for %s' % (host, port, headers['st']))
- logger.info('Discovery request for %s' % headers['st'])
-
- # Do we know about this service?
- for i in list(self.known.values()):
- if i['MANIFESTATION'] == 'remote':
- continue
- if headers['st'] == 'ssdp:all' and i['SILENT']:
- continue
- if i['ST'] == headers['st'] or headers['st'] == 'ssdp:all':
- response = ['HTTP/1.1 200 OK']
-
- usn = None
- for k, v in list(i.items()):
- if k == 'USN':
- usn = v
- if k not in ('MANIFESTATION', 'SILENT', 'HOST'):
- response.append('%s: %s' % (k, v))
-
- if usn:
- response.append('DATE: %s' % formatdate(timeval=None, localtime=False, usegmt=True))
-
- response.extend(('', ''))
- delay = random.randint(0, int(headers['mx']))
-
- self.send_it('\r\n'.join(response), (host, port), delay, usn)
-
- def do_notify(self, usn):
- """Do notification"""
-
- if self.known[usn]['SILENT']:
- return
- logger.info('Sending alive notification for %s' % usn)
-
- resp = [
- 'NOTIFY * HTTP/1.1',
- 'HOST: %s:%d' % (SSDP_ADDR, self.ssdp_port),
- 'NTS: ssdp:alive',
- ]
- stcpy = dict(list(self.known[usn].items()))
- stcpy['NT'] = stcpy['ST']
- del stcpy['ST']
- del stcpy['MANIFESTATION']
- del stcpy['SILENT']
- del stcpy['HOST']
- del stcpy['last-seen']
-
- resp.extend([': '.join(x) for x in list(stcpy.items())])
- resp.extend(('', ''))
- logger.debug('do_notify content', resp)
- try:
- self.sock.sendto('\r\n'.join(resp).encode(), (SSDP_ADDR, self.ssdp_port))
- self.sock.sendto('\r\n'.join(resp).encode(), (SSDP_ADDR, self.ssdp_port))
- except (AttributeError, socket.error) as msg:
- logger.warning("failure sending out alive notification: %r" % msg)
-
- def do_byebye(self, usn):
- """Do byebye"""
-
- logger.info('Sending byebye notification for %s' % usn)
-
- resp = [
- 'NOTIFY * HTTP/1.1',
- 'HOST: %s:%d' % (SSDP_ADDR, self.ssdp_port),
- 'NTS: ssdp:byebye',
- ]
- try:
- stcpy = dict(list(self.known[usn].items()))
- stcpy['NT'] = stcpy['ST']
- del stcpy['ST']
- del stcpy['MANIFESTATION']
- del stcpy['SILENT']
- del stcpy['HOST']
- del stcpy['last-seen']
- resp.extend([': '.join(x) for x in list(stcpy.items())])
- resp.extend(('', ''))
- logger.debug('do_byebye content', resp)
- if self.sock:
- try:
- self.sock.sendto('\r\n'.join(resp), (SSDP_ADDR, self.ssdp_port))
- except (AttributeError, socket.error) as msg:
- logger.error("failure sending out byebye notification: %r" % msg)
- except KeyError as msg:
- logger.error("error building byebye notification: %r" % msg)
From 0776ca420ad78b2b2f1af30e37a617a7450a7fd6 Mon Sep 17 00:00:00 2001
From: deathbybandaid
Date: Sun, 1 Nov 2020 14:08:31 -0500
Subject: [PATCH 2/2] Update Version
---
fHDHR/__init__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fHDHR/__init__.py b/fHDHR/__init__.py
index 6835110..785bac4 100644
--- a/fHDHR/__init__.py
+++ b/fHDHR/__init__.py
@@ -1,2 +1,2 @@
# coding=utf-8
-fHDHR_VERSION = "v0.2.9-beta"
+fHDHR_VERSION = "v0.3.0-beta"