From 35c85b840c30cc956218dfd73f825d87f7b9ed68 Mon Sep 17 00:00:00 2001 From: deathbybandaid Date: Tue, 8 Dec 2020 08:19:20 -0500 Subject: [PATCH 1/8] Channel Creation timestamp and allow Origin to set Enablement --- fHDHR/device/channels/channel.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/fHDHR/device/channels/channel.py b/fHDHR/device/channels/channel.py index c3ccff2..299486f 100644 --- a/fHDHR/device/channels/channel.py +++ b/fHDHR/device/channels/channel.py @@ -1,3 +1,4 @@ +import time class Channel(): @@ -15,6 +16,7 @@ class Channel(): self.channel_id = channel_id self.dict = self.fhdhr.db.get_channel_value(str(channel_id), "dict") or self.default_dict self.verify_dict() + self.fhdhr.db.set_channel_value(self.dict["id"], "dict", self.dict) @property @@ -89,6 +91,13 @@ class Channel(): channel_info["HD"] = 0 self.dict["HD"] = channel_info["HD"] + if "enabled" in list(channel_info.keys()): + if "created" not in list(self.dict.keys()): + self.dict["enabled"] = channel_info["enabled"] + + if "created" not in list(self.dict.keys()): + self.dict["created"] = time.time() + self.fhdhr.db.set_channel_value(self.dict["id"], "dict", self.dict) @property From 0afe2339a3f17e2598a4a50e0848492b4e04d2ed Mon Sep 17 00:00:00 2001 From: deathbybandaid Date: Tue, 8 Dec 2020 08:43:46 -0500 Subject: [PATCH 2/8] Increase Channel Creation Logging --- fHDHR/device/channels/__init__.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/fHDHR/device/channels/__init__.py b/fHDHR/device/channels/__init__.py index 99631a7..74c3177 100644 --- a/fHDHR/device/channels/__init__.py +++ b/fHDHR/device/channels/__init__.py @@ -71,22 +71,34 @@ class Channels(): if updatelist: channel_origin_id_list = [str(self.list[x].dict["origin_id"]) for x in list(self.list.keys())] + self.fhdhr.logger.info("Performing Channel Scan.") + channel_dict_list = self.origin.get_channels() + self.fhdhr.logger.info("Found %s channels for %s." % (len(channel_dict_list), self.fhdhr.config.dict["main"]["servicename"])) + + newchan = 0 for channel_info in channel_dict_list: + chan_existing = False if str(channel_info["id"]) in channel_origin_id_list: chan_existing = True channel_obj = self.get_channel_obj("origin_id", channel_info["id"]) else: channel_obj = Channel(self.fhdhr, self.id_system, origin_id=channel_info["id"]) + channel_id = channel_obj.dict["id"] channel_obj.basics(channel_info) if not chan_existing: self.list[channel_id] = channel_obj + newchan += 1 + + if not newchan: + newchan = "no" + self.fhdhr.logger.info("Found %s NEW channels." % newchan) + + self.fhdhr.logger.info("Total Channel Count: %s" % len(self.list.keys())) - if not self.list_update_time: - self.fhdhr.logger.info("Found " + str(len(self.list)) + " channels for " + str(self.fhdhr.config.dict["main"]["servicename"])) self.list_update_time = datetime.datetime.now() self.fhdhr.db.set_fhdhr_value("channels", "scanned_time", time.time()) From 835f98db436207daf086243368d905367c216f50 Mon Sep 17 00:00:00 2001 From: deathbybandaid Date: Tue, 8 Dec 2020 09:10:35 -0500 Subject: [PATCH 3/8] Update Versions --- fHDHR/__init__.py | 2 +- fHDHR/cli/run.py | 9 +++++---- fHDHR/config/__init__.py | 6 +++++- origin/__init__.py | 3 +++ 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/fHDHR/__init__.py b/fHDHR/__init__.py index 6f03062..9dada5c 100644 --- a/fHDHR/__init__.py +++ b/fHDHR/__init__.py @@ -5,7 +5,7 @@ from .device import fHDHR_Device import fHDHR.tools -fHDHR_VERSION = "v0.4.5-beta" +fHDHR_VERSION = "v0.4.6-beta" class fHDHR_INT_OBJ(): diff --git a/fHDHR/cli/run.py b/fHDHR/cli/run.py index 411b6a0..67af119 100644 --- a/fHDHR/cli/run.py +++ b/fHDHR/cli/run.py @@ -32,10 +32,10 @@ def build_args_parser(): return parser.parse_args() -def get_configuration(args, script_dir): +def get_configuration(args, script_dir, origin): if not os.path.isfile(args.cfg): raise fHDHR.exceptions.ConfigurationNotFound(filename=args.cfg) - return fHDHR.config.Config(args.cfg, script_dir) + return fHDHR.config.Config(args.cfg, script_dir, origin) def run(settings, logger, db, alternative_epg, origin): @@ -85,7 +85,7 @@ def start(args, script_dir, alternative_epg, origin): """Get Configuration for fHDHR and start""" try: - settings = get_configuration(args, script_dir) + settings = get_configuration(args, script_dir, origin) except fHDHR.exceptions.ConfigurationError as e: print(e) return ERR_CODE_NO_RESTART @@ -100,7 +100,8 @@ def start(args, script_dir, alternative_epg, origin): def main(script_dir, alternative_epg, origin): """fHDHR run script entry point""" - print("Loading fHDHR " + fHDHR_VERSION) + print("Loading fHDHR %s" % fHDHR_VERSION) + print("Loading Origin Service: %s %s" % (origin.ORIGIN_NAME, origin.ORIGIN_VERSION)) try: args = build_args_parser() diff --git a/fHDHR/config/__init__.py b/fHDHR/config/__init__.py index 9d8e260..df69b5a 100644 --- a/fHDHR/config/__init__.py +++ b/fHDHR/config/__init__.py @@ -15,7 +15,9 @@ from fHDHR.tools import isint, isfloat, is_arithmetic, is_docker class Config(): - def __init__(self, filename, script_dir): + def __init__(self, filename, script_dir, origin): + self.origin = origin + self.internal = {} self.conf_default = {} self.dict = {} @@ -64,6 +66,8 @@ class Config(): self.internal["versions"]["fHDHR"] = fHDHR_VERSION + self.internal["versions"][self.origin.ORIGIN_NAME] = self.origin.ORIGIN_VERSION + self.internal["versions"]["Python"] = sys.version opersystem = platform.system() diff --git a/origin/__init__.py b/origin/__init__.py index bfebf0f..6f01e4f 100644 --- a/origin/__init__.py +++ b/origin/__init__.py @@ -2,3 +2,6 @@ from .origin_service import * from .origin_channels import * from .origin_epg import * + +ORIGIN_NAME = "fHDHR_NextPVR" +ORIGIN_VERSION = "v0.5.0-beta" From c389801a487820c2064b9d5d65e0bc5b4171a744 Mon Sep 17 00:00:00 2001 From: deathbybandaid Date: Tue, 8 Dec 2020 09:27:51 -0500 Subject: [PATCH 4/8] Seperate fHDHR_web --- fHDHR/__init__.py | 2 +- fHDHR/cli/run.py | 16 ++++++++-------- {fHDHR/http => fHDHR_web}/__init__.py | 3 +++ {fHDHR/http => fHDHR_web}/api/__init__.py | 0 {fHDHR/http => fHDHR_web}/api/channels.py | 0 {fHDHR/http => fHDHR_web}/api/cluster.py | 0 {fHDHR/http => fHDHR_web}/api/debug.py | 0 {fHDHR/http => fHDHR_web}/api/epg.py | 0 {fHDHR/http => fHDHR_web}/api/images.py | 0 {fHDHR/http => fHDHR_web}/api/m3u.py | 0 {fHDHR/http => fHDHR_web}/api/root_url.py | 0 {fHDHR/http => fHDHR_web}/api/settings.py | 0 {fHDHR/http => fHDHR_web}/api/tuners.py | 0 {fHDHR/http => fHDHR_web}/api/xmltv.py | 0 {fHDHR/http => fHDHR_web}/files/__init__.py | 0 {fHDHR/http => fHDHR_web}/files/device_xml.py | 0 {fHDHR/http => fHDHR_web}/files/favicon_ico.py | 0 {fHDHR/http => fHDHR_web}/files/style_css.py | 0 {fHDHR/http => fHDHR_web}/hdhr/__init__.py | 0 {fHDHR/http => fHDHR_web}/hdhr/auto.py | 0 {fHDHR/http => fHDHR_web}/hdhr/device_xml.py | 0 {fHDHR/http => fHDHR_web}/hdhr/discover_json.py | 0 {fHDHR/http => fHDHR_web}/hdhr/lineup_json.py | 0 {fHDHR/http => fHDHR_web}/hdhr/lineup_post.py | 0 .../hdhr/lineup_status_json.py | 0 {fHDHR/http => fHDHR_web}/hdhr/lineup_xml.py | 0 {fHDHR/http => fHDHR_web}/hdhr/tuner.py | 0 {fHDHR/http => fHDHR_web}/pages/__init__.py | 0 .../http => fHDHR_web}/pages/channels_editor.py | 0 {fHDHR/http => fHDHR_web}/pages/channels_html.py | 0 {fHDHR/http => fHDHR_web}/pages/cluster_html.py | 0 .../http => fHDHR_web}/pages/diagnostics_html.py | 0 {fHDHR/http => fHDHR_web}/pages/guide_html.py | 0 {fHDHR/http => fHDHR_web}/pages/index_html.py | 0 {fHDHR/http => fHDHR_web}/pages/origin_html.py | 0 {fHDHR/http => fHDHR_web}/pages/settings_html.py | 0 {fHDHR/http => fHDHR_web}/pages/tuners_html.py | 0 {fHDHR/http => fHDHR_web}/pages/version_html.py | 0 {fHDHR/http => fHDHR_web}/pages/xmltv_html.py | 0 {fHDHR/http => fHDHR_web}/rmg/__init__.py | 0 {fHDHR/http => fHDHR_web}/rmg/device_xml.py | 0 .../http => fHDHR_web}/rmg/devices_devicekey.py | 0 .../rmg/devices_devicekey_channels.py | 0 .../rmg/devices_devicekey_media.py | 0 .../rmg/devices_devicekey_networks.py | 0 .../rmg/devices_devicekey_prefs.py | 0 .../rmg/devices_devicekey_scan.py | 0 .../rmg/devices_devicekey_scanners.py | 0 .../http => fHDHR_web}/rmg/devices_discover.py | 0 {fHDHR/http => fHDHR_web}/rmg/devices_probe.py | 0 {fHDHR/http => fHDHR_web}/rmg/rmg_ident_xml.py | 0 51 files changed, 12 insertions(+), 9 deletions(-) rename {fHDHR/http => fHDHR_web}/__init__.py (99%) rename {fHDHR/http => fHDHR_web}/api/__init__.py (100%) rename {fHDHR/http => fHDHR_web}/api/channels.py (100%) rename {fHDHR/http => fHDHR_web}/api/cluster.py (100%) rename {fHDHR/http => fHDHR_web}/api/debug.py (100%) rename {fHDHR/http => fHDHR_web}/api/epg.py (100%) rename {fHDHR/http => fHDHR_web}/api/images.py (100%) rename {fHDHR/http => fHDHR_web}/api/m3u.py (100%) rename {fHDHR/http => fHDHR_web}/api/root_url.py (100%) rename {fHDHR/http => fHDHR_web}/api/settings.py (100%) rename {fHDHR/http => fHDHR_web}/api/tuners.py (100%) rename {fHDHR/http => fHDHR_web}/api/xmltv.py (100%) rename {fHDHR/http => fHDHR_web}/files/__init__.py (100%) rename {fHDHR/http => fHDHR_web}/files/device_xml.py (100%) rename {fHDHR/http => fHDHR_web}/files/favicon_ico.py (100%) rename {fHDHR/http => fHDHR_web}/files/style_css.py (100%) rename {fHDHR/http => fHDHR_web}/hdhr/__init__.py (100%) rename {fHDHR/http => fHDHR_web}/hdhr/auto.py (100%) rename {fHDHR/http => fHDHR_web}/hdhr/device_xml.py (100%) rename {fHDHR/http => fHDHR_web}/hdhr/discover_json.py (100%) rename {fHDHR/http => fHDHR_web}/hdhr/lineup_json.py (100%) rename {fHDHR/http => fHDHR_web}/hdhr/lineup_post.py (100%) rename {fHDHR/http => fHDHR_web}/hdhr/lineup_status_json.py (100%) rename {fHDHR/http => fHDHR_web}/hdhr/lineup_xml.py (100%) rename {fHDHR/http => fHDHR_web}/hdhr/tuner.py (100%) rename {fHDHR/http => fHDHR_web}/pages/__init__.py (100%) rename {fHDHR/http => fHDHR_web}/pages/channels_editor.py (100%) rename {fHDHR/http => fHDHR_web}/pages/channels_html.py (100%) rename {fHDHR/http => fHDHR_web}/pages/cluster_html.py (100%) rename {fHDHR/http => fHDHR_web}/pages/diagnostics_html.py (100%) rename {fHDHR/http => fHDHR_web}/pages/guide_html.py (100%) rename {fHDHR/http => fHDHR_web}/pages/index_html.py (100%) rename {fHDHR/http => fHDHR_web}/pages/origin_html.py (100%) rename {fHDHR/http => fHDHR_web}/pages/settings_html.py (100%) rename {fHDHR/http => fHDHR_web}/pages/tuners_html.py (100%) rename {fHDHR/http => fHDHR_web}/pages/version_html.py (100%) rename {fHDHR/http => fHDHR_web}/pages/xmltv_html.py (100%) rename {fHDHR/http => fHDHR_web}/rmg/__init__.py (100%) rename {fHDHR/http => fHDHR_web}/rmg/device_xml.py (100%) rename {fHDHR/http => fHDHR_web}/rmg/devices_devicekey.py (100%) rename {fHDHR/http => fHDHR_web}/rmg/devices_devicekey_channels.py (100%) rename {fHDHR/http => fHDHR_web}/rmg/devices_devicekey_media.py (100%) rename {fHDHR/http => fHDHR_web}/rmg/devices_devicekey_networks.py (100%) rename {fHDHR/http => fHDHR_web}/rmg/devices_devicekey_prefs.py (100%) rename {fHDHR/http => fHDHR_web}/rmg/devices_devicekey_scan.py (100%) rename {fHDHR/http => fHDHR_web}/rmg/devices_devicekey_scanners.py (100%) rename {fHDHR/http => fHDHR_web}/rmg/devices_discover.py (100%) rename {fHDHR/http => fHDHR_web}/rmg/devices_probe.py (100%) rename {fHDHR/http => fHDHR_web}/rmg/rmg_ident_xml.py (100%) diff --git a/fHDHR/__init__.py b/fHDHR/__init__.py index 9dada5c..a8e9384 100644 --- a/fHDHR/__init__.py +++ b/fHDHR/__init__.py @@ -21,7 +21,7 @@ class fHDHR_INT_OBJ(): class fHDHR_OBJ(): - def __init__(self, settings, logger, db, alternative_epg, origin): + def __init__(self, settings, logger, db, origin, alternative_epg): self.fhdhr = fHDHR_INT_OBJ(settings, logger, db) self.originwrapper = OriginServiceWrapper(self.fhdhr, origin) diff --git a/fHDHR/cli/run.py b/fHDHR/cli/run.py index 67af119..6a90246 100644 --- a/fHDHR/cli/run.py +++ b/fHDHR/cli/run.py @@ -9,7 +9,6 @@ import platform from fHDHR import fHDHR_VERSION, fHDHR_OBJ import fHDHR.exceptions import fHDHR.config -from fHDHR.http import fHDHR_HTTP_Server from fHDHR.db import fHDHRdb ERR_CODE = 1 @@ -38,10 +37,10 @@ def get_configuration(args, script_dir, origin): return fHDHR.config.Config(args.cfg, script_dir, origin) -def run(settings, logger, db, alternative_epg, origin): +def run(settings, logger, db, script_dir, fHDHR_web, origin, alternative_epg): - fhdhr = fHDHR_OBJ(settings, logger, db, alternative_epg, origin) - fhdhrweb = fHDHR_HTTP_Server(fhdhr) + fhdhr = fHDHR_OBJ(settings, logger, db, origin, alternative_epg) + fhdhrweb = fHDHR_web.fHDHR_HTTP_Server(fhdhr) try: @@ -81,7 +80,7 @@ def run(settings, logger, db, alternative_epg, origin): return ERR_CODE -def start(args, script_dir, alternative_epg, origin): +def start(args, script_dir, fHDHR_web, origin, alternative_epg): """Get Configuration for fHDHR and start""" try: @@ -94,18 +93,19 @@ def start(args, script_dir, alternative_epg, origin): db = fHDHRdb(settings) - return run(settings, logger, db, alternative_epg, origin) + return run(settings, logger, db, script_dir, fHDHR_web, origin, alternative_epg) -def main(script_dir, alternative_epg, origin): +def main(script_dir, fHDHR_web, origin, alternative_epg): """fHDHR run script entry point""" print("Loading fHDHR %s" % fHDHR_VERSION) + print("Loading fHDHR_web %s" % fHDHR_web.fHDHR_web_VERSION) print("Loading Origin Service: %s %s" % (origin.ORIGIN_NAME, origin.ORIGIN_VERSION)) try: args = build_args_parser() - return start(args, script_dir, alternative_epg, origin) + return start(args, script_dir, fHDHR_web, origin, alternative_epg) except KeyboardInterrupt: print("\n\nInterrupted") return ERR_CODE diff --git a/fHDHR/http/__init__.py b/fHDHR_web/__init__.py similarity index 99% rename from fHDHR/http/__init__.py rename to fHDHR_web/__init__.py index ab75db5..86b9742 100644 --- a/fHDHR/http/__init__.py +++ b/fHDHR_web/__init__.py @@ -8,6 +8,9 @@ from .rmg import fHDHR_RMG from .api import fHDHR_API +fHDHR_web_VERSION = "v0.4.0-beta" + + class fHDHR_HTTP_Server(): app = None diff --git a/fHDHR/http/api/__init__.py b/fHDHR_web/api/__init__.py similarity index 100% rename from fHDHR/http/api/__init__.py rename to fHDHR_web/api/__init__.py diff --git a/fHDHR/http/api/channels.py b/fHDHR_web/api/channels.py similarity index 100% rename from fHDHR/http/api/channels.py rename to fHDHR_web/api/channels.py diff --git a/fHDHR/http/api/cluster.py b/fHDHR_web/api/cluster.py similarity index 100% rename from fHDHR/http/api/cluster.py rename to fHDHR_web/api/cluster.py diff --git a/fHDHR/http/api/debug.py b/fHDHR_web/api/debug.py similarity index 100% rename from fHDHR/http/api/debug.py rename to fHDHR_web/api/debug.py diff --git a/fHDHR/http/api/epg.py b/fHDHR_web/api/epg.py similarity index 100% rename from fHDHR/http/api/epg.py rename to fHDHR_web/api/epg.py diff --git a/fHDHR/http/api/images.py b/fHDHR_web/api/images.py similarity index 100% rename from fHDHR/http/api/images.py rename to fHDHR_web/api/images.py diff --git a/fHDHR/http/api/m3u.py b/fHDHR_web/api/m3u.py similarity index 100% rename from fHDHR/http/api/m3u.py rename to fHDHR_web/api/m3u.py diff --git a/fHDHR/http/api/root_url.py b/fHDHR_web/api/root_url.py similarity index 100% rename from fHDHR/http/api/root_url.py rename to fHDHR_web/api/root_url.py diff --git a/fHDHR/http/api/settings.py b/fHDHR_web/api/settings.py similarity index 100% rename from fHDHR/http/api/settings.py rename to fHDHR_web/api/settings.py diff --git a/fHDHR/http/api/tuners.py b/fHDHR_web/api/tuners.py similarity index 100% rename from fHDHR/http/api/tuners.py rename to fHDHR_web/api/tuners.py diff --git a/fHDHR/http/api/xmltv.py b/fHDHR_web/api/xmltv.py similarity index 100% rename from fHDHR/http/api/xmltv.py rename to fHDHR_web/api/xmltv.py diff --git a/fHDHR/http/files/__init__.py b/fHDHR_web/files/__init__.py similarity index 100% rename from fHDHR/http/files/__init__.py rename to fHDHR_web/files/__init__.py diff --git a/fHDHR/http/files/device_xml.py b/fHDHR_web/files/device_xml.py similarity index 100% rename from fHDHR/http/files/device_xml.py rename to fHDHR_web/files/device_xml.py diff --git a/fHDHR/http/files/favicon_ico.py b/fHDHR_web/files/favicon_ico.py similarity index 100% rename from fHDHR/http/files/favicon_ico.py rename to fHDHR_web/files/favicon_ico.py diff --git a/fHDHR/http/files/style_css.py b/fHDHR_web/files/style_css.py similarity index 100% rename from fHDHR/http/files/style_css.py rename to fHDHR_web/files/style_css.py diff --git a/fHDHR/http/hdhr/__init__.py b/fHDHR_web/hdhr/__init__.py similarity index 100% rename from fHDHR/http/hdhr/__init__.py rename to fHDHR_web/hdhr/__init__.py diff --git a/fHDHR/http/hdhr/auto.py b/fHDHR_web/hdhr/auto.py similarity index 100% rename from fHDHR/http/hdhr/auto.py rename to fHDHR_web/hdhr/auto.py diff --git a/fHDHR/http/hdhr/device_xml.py b/fHDHR_web/hdhr/device_xml.py similarity index 100% rename from fHDHR/http/hdhr/device_xml.py rename to fHDHR_web/hdhr/device_xml.py diff --git a/fHDHR/http/hdhr/discover_json.py b/fHDHR_web/hdhr/discover_json.py similarity index 100% rename from fHDHR/http/hdhr/discover_json.py rename to fHDHR_web/hdhr/discover_json.py diff --git a/fHDHR/http/hdhr/lineup_json.py b/fHDHR_web/hdhr/lineup_json.py similarity index 100% rename from fHDHR/http/hdhr/lineup_json.py rename to fHDHR_web/hdhr/lineup_json.py diff --git a/fHDHR/http/hdhr/lineup_post.py b/fHDHR_web/hdhr/lineup_post.py similarity index 100% rename from fHDHR/http/hdhr/lineup_post.py rename to fHDHR_web/hdhr/lineup_post.py diff --git a/fHDHR/http/hdhr/lineup_status_json.py b/fHDHR_web/hdhr/lineup_status_json.py similarity index 100% rename from fHDHR/http/hdhr/lineup_status_json.py rename to fHDHR_web/hdhr/lineup_status_json.py diff --git a/fHDHR/http/hdhr/lineup_xml.py b/fHDHR_web/hdhr/lineup_xml.py similarity index 100% rename from fHDHR/http/hdhr/lineup_xml.py rename to fHDHR_web/hdhr/lineup_xml.py diff --git a/fHDHR/http/hdhr/tuner.py b/fHDHR_web/hdhr/tuner.py similarity index 100% rename from fHDHR/http/hdhr/tuner.py rename to fHDHR_web/hdhr/tuner.py diff --git a/fHDHR/http/pages/__init__.py b/fHDHR_web/pages/__init__.py similarity index 100% rename from fHDHR/http/pages/__init__.py rename to fHDHR_web/pages/__init__.py diff --git a/fHDHR/http/pages/channels_editor.py b/fHDHR_web/pages/channels_editor.py similarity index 100% rename from fHDHR/http/pages/channels_editor.py rename to fHDHR_web/pages/channels_editor.py diff --git a/fHDHR/http/pages/channels_html.py b/fHDHR_web/pages/channels_html.py similarity index 100% rename from fHDHR/http/pages/channels_html.py rename to fHDHR_web/pages/channels_html.py diff --git a/fHDHR/http/pages/cluster_html.py b/fHDHR_web/pages/cluster_html.py similarity index 100% rename from fHDHR/http/pages/cluster_html.py rename to fHDHR_web/pages/cluster_html.py diff --git a/fHDHR/http/pages/diagnostics_html.py b/fHDHR_web/pages/diagnostics_html.py similarity index 100% rename from fHDHR/http/pages/diagnostics_html.py rename to fHDHR_web/pages/diagnostics_html.py diff --git a/fHDHR/http/pages/guide_html.py b/fHDHR_web/pages/guide_html.py similarity index 100% rename from fHDHR/http/pages/guide_html.py rename to fHDHR_web/pages/guide_html.py diff --git a/fHDHR/http/pages/index_html.py b/fHDHR_web/pages/index_html.py similarity index 100% rename from fHDHR/http/pages/index_html.py rename to fHDHR_web/pages/index_html.py diff --git a/fHDHR/http/pages/origin_html.py b/fHDHR_web/pages/origin_html.py similarity index 100% rename from fHDHR/http/pages/origin_html.py rename to fHDHR_web/pages/origin_html.py diff --git a/fHDHR/http/pages/settings_html.py b/fHDHR_web/pages/settings_html.py similarity index 100% rename from fHDHR/http/pages/settings_html.py rename to fHDHR_web/pages/settings_html.py diff --git a/fHDHR/http/pages/tuners_html.py b/fHDHR_web/pages/tuners_html.py similarity index 100% rename from fHDHR/http/pages/tuners_html.py rename to fHDHR_web/pages/tuners_html.py diff --git a/fHDHR/http/pages/version_html.py b/fHDHR_web/pages/version_html.py similarity index 100% rename from fHDHR/http/pages/version_html.py rename to fHDHR_web/pages/version_html.py diff --git a/fHDHR/http/pages/xmltv_html.py b/fHDHR_web/pages/xmltv_html.py similarity index 100% rename from fHDHR/http/pages/xmltv_html.py rename to fHDHR_web/pages/xmltv_html.py diff --git a/fHDHR/http/rmg/__init__.py b/fHDHR_web/rmg/__init__.py similarity index 100% rename from fHDHR/http/rmg/__init__.py rename to fHDHR_web/rmg/__init__.py diff --git a/fHDHR/http/rmg/device_xml.py b/fHDHR_web/rmg/device_xml.py similarity index 100% rename from fHDHR/http/rmg/device_xml.py rename to fHDHR_web/rmg/device_xml.py diff --git a/fHDHR/http/rmg/devices_devicekey.py b/fHDHR_web/rmg/devices_devicekey.py similarity index 100% rename from fHDHR/http/rmg/devices_devicekey.py rename to fHDHR_web/rmg/devices_devicekey.py diff --git a/fHDHR/http/rmg/devices_devicekey_channels.py b/fHDHR_web/rmg/devices_devicekey_channels.py similarity index 100% rename from fHDHR/http/rmg/devices_devicekey_channels.py rename to fHDHR_web/rmg/devices_devicekey_channels.py diff --git a/fHDHR/http/rmg/devices_devicekey_media.py b/fHDHR_web/rmg/devices_devicekey_media.py similarity index 100% rename from fHDHR/http/rmg/devices_devicekey_media.py rename to fHDHR_web/rmg/devices_devicekey_media.py diff --git a/fHDHR/http/rmg/devices_devicekey_networks.py b/fHDHR_web/rmg/devices_devicekey_networks.py similarity index 100% rename from fHDHR/http/rmg/devices_devicekey_networks.py rename to fHDHR_web/rmg/devices_devicekey_networks.py diff --git a/fHDHR/http/rmg/devices_devicekey_prefs.py b/fHDHR_web/rmg/devices_devicekey_prefs.py similarity index 100% rename from fHDHR/http/rmg/devices_devicekey_prefs.py rename to fHDHR_web/rmg/devices_devicekey_prefs.py diff --git a/fHDHR/http/rmg/devices_devicekey_scan.py b/fHDHR_web/rmg/devices_devicekey_scan.py similarity index 100% rename from fHDHR/http/rmg/devices_devicekey_scan.py rename to fHDHR_web/rmg/devices_devicekey_scan.py diff --git a/fHDHR/http/rmg/devices_devicekey_scanners.py b/fHDHR_web/rmg/devices_devicekey_scanners.py similarity index 100% rename from fHDHR/http/rmg/devices_devicekey_scanners.py rename to fHDHR_web/rmg/devices_devicekey_scanners.py diff --git a/fHDHR/http/rmg/devices_discover.py b/fHDHR_web/rmg/devices_discover.py similarity index 100% rename from fHDHR/http/rmg/devices_discover.py rename to fHDHR_web/rmg/devices_discover.py diff --git a/fHDHR/http/rmg/devices_probe.py b/fHDHR_web/rmg/devices_probe.py similarity index 100% rename from fHDHR/http/rmg/devices_probe.py rename to fHDHR_web/rmg/devices_probe.py diff --git a/fHDHR/http/rmg/rmg_ident_xml.py b/fHDHR_web/rmg/rmg_ident_xml.py similarity index 100% rename from fHDHR/http/rmg/rmg_ident_xml.py rename to fHDHR_web/rmg/rmg_ident_xml.py From 0bf33c32099b0290b185a41de0ef515299b5105f Mon Sep 17 00:00:00 2001 From: deathbybandaid Date: Tue, 8 Dec 2020 09:42:41 -0500 Subject: [PATCH 5/8] Move Web related data to fHDHR_web --- fHDHR/config/__init__.py | 5 +++-- {data/www => fHDHR_web}/templates/base.html | 0 {data/www => fHDHR_web}/templates/channels.html | 0 .../templates/channels_editor.html | 0 {data/www => fHDHR_web}/templates/cluster.html | 0 {data/www => fHDHR_web}/templates/diagnostics.html | 0 {data/www => fHDHR_web}/templates/guide.html | 0 {data/www => fHDHR_web}/templates/index.html | 0 {data/www => fHDHR_web}/templates/origin.html | 0 {data/www => fHDHR_web}/templates/settings.html | 0 {data/www => fHDHR_web}/templates/tuners.html | 0 {data/www => fHDHR_web}/templates/version.html | 0 {data/www => fHDHR_web}/templates/xmltv.html | 0 {data/www => fHDHR_web/www_dir}/favicon.ico | Bin {data/www => fHDHR_web/www_dir}/style.css | 0 15 files changed, 3 insertions(+), 2 deletions(-) rename {data/www => fHDHR_web}/templates/base.html (100%) rename {data/www => fHDHR_web}/templates/channels.html (100%) rename {data/www => fHDHR_web}/templates/channels_editor.html (100%) rename {data/www => fHDHR_web}/templates/cluster.html (100%) rename {data/www => fHDHR_web}/templates/diagnostics.html (100%) rename {data/www => fHDHR_web}/templates/guide.html (100%) rename {data/www => fHDHR_web}/templates/index.html (100%) rename {data/www => fHDHR_web}/templates/origin.html (100%) rename {data/www => fHDHR_web}/templates/settings.html (100%) rename {data/www => fHDHR_web}/templates/tuners.html (100%) rename {data/www => fHDHR_web}/templates/version.html (100%) rename {data/www => fHDHR_web}/templates/xmltv.html (100%) rename {data/www => fHDHR_web/www_dir}/favicon.ico (100%) rename {data/www => fHDHR_web/www_dir}/style.css (100%) diff --git a/fHDHR/config/__init__.py b/fHDHR/config/__init__.py index df69b5a..e0784f9 100644 --- a/fHDHR/config/__init__.py +++ b/fHDHR/config/__init__.py @@ -29,7 +29,8 @@ class Config(): def initial_load(self, script_dir): data_dir = pathlib.Path(script_dir).joinpath('data') - www_dir = pathlib.Path(data_dir).joinpath('www') + fHDHR_web_dir = pathlib.Path(script_dir).joinpath('fHDHR_web') + www_dir = pathlib.Path(fHDHR_web_dir).joinpath('www_dir') self.internal["paths"] = { "script_dir": script_dir, @@ -39,7 +40,7 @@ class Config(): "cache_dir": pathlib.Path(data_dir).joinpath('cache'), "internal_config": pathlib.Path(data_dir).joinpath('internal_config'), "www_dir": www_dir, - "www_templates_dir": pathlib.Path(www_dir).joinpath('templates'), + "www_templates_dir": pathlib.Path(fHDHR_web_dir).joinpath('templates'), "font": pathlib.Path(data_dir).joinpath('garamond.ttf'), } diff --git a/data/www/templates/base.html b/fHDHR_web/templates/base.html similarity index 100% rename from data/www/templates/base.html rename to fHDHR_web/templates/base.html diff --git a/data/www/templates/channels.html b/fHDHR_web/templates/channels.html similarity index 100% rename from data/www/templates/channels.html rename to fHDHR_web/templates/channels.html diff --git a/data/www/templates/channels_editor.html b/fHDHR_web/templates/channels_editor.html similarity index 100% rename from data/www/templates/channels_editor.html rename to fHDHR_web/templates/channels_editor.html diff --git a/data/www/templates/cluster.html b/fHDHR_web/templates/cluster.html similarity index 100% rename from data/www/templates/cluster.html rename to fHDHR_web/templates/cluster.html diff --git a/data/www/templates/diagnostics.html b/fHDHR_web/templates/diagnostics.html similarity index 100% rename from data/www/templates/diagnostics.html rename to fHDHR_web/templates/diagnostics.html diff --git a/data/www/templates/guide.html b/fHDHR_web/templates/guide.html similarity index 100% rename from data/www/templates/guide.html rename to fHDHR_web/templates/guide.html diff --git a/data/www/templates/index.html b/fHDHR_web/templates/index.html similarity index 100% rename from data/www/templates/index.html rename to fHDHR_web/templates/index.html diff --git a/data/www/templates/origin.html b/fHDHR_web/templates/origin.html similarity index 100% rename from data/www/templates/origin.html rename to fHDHR_web/templates/origin.html diff --git a/data/www/templates/settings.html b/fHDHR_web/templates/settings.html similarity index 100% rename from data/www/templates/settings.html rename to fHDHR_web/templates/settings.html diff --git a/data/www/templates/tuners.html b/fHDHR_web/templates/tuners.html similarity index 100% rename from data/www/templates/tuners.html rename to fHDHR_web/templates/tuners.html diff --git a/data/www/templates/version.html b/fHDHR_web/templates/version.html similarity index 100% rename from data/www/templates/version.html rename to fHDHR_web/templates/version.html diff --git a/data/www/templates/xmltv.html b/fHDHR_web/templates/xmltv.html similarity index 100% rename from data/www/templates/xmltv.html rename to fHDHR_web/templates/xmltv.html diff --git a/data/www/favicon.ico b/fHDHR_web/www_dir/favicon.ico similarity index 100% rename from data/www/favicon.ico rename to fHDHR_web/www_dir/favicon.ico diff --git a/data/www/style.css b/fHDHR_web/www_dir/style.css similarity index 100% rename from data/www/style.css rename to fHDHR_web/www_dir/style.css From 5d4373f5038c3a9c41818548dd0492a4cf8cd1cf Mon Sep 17 00:00:00 2001 From: deathbybandaid Date: Tue, 8 Dec 2020 09:45:32 -0500 Subject: [PATCH 6/8] Update main Loader tor reflect prior commits --- main.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main.py b/main.py index 9e838e8..ab7773e 100644 --- a/main.py +++ b/main.py @@ -9,6 +9,7 @@ import pathlib from multiprocessing import freeze_support from fHDHR.cli import run +import fHDHR_web import alternative_epg import origin @@ -16,4 +17,4 @@ SCRIPT_DIR = pathlib.Path(os.path.dirname(os.path.abspath(__file__))) if __name__ == '__main__': freeze_support() - sys.exit(run.main(SCRIPT_DIR, alternative_epg, origin)) + sys.exit(run.main(SCRIPT_DIR, fHDHR_web, origin, alternative_epg)) From 0304bdb5e5b5570d2dd681206ebd40f744677925 Mon Sep 17 00:00:00 2001 From: deathbybandaid Date: Tue, 8 Dec 2020 12:17:55 -0500 Subject: [PATCH 7/8] Enhancements --- data/internal_config/ssdp.json | 19 +++- fHDHR/__init__.py | 3 + fHDHR/api/__init__.py | 36 ++++++ fHDHR/device/cluster.py | 29 ++--- fHDHR/device/epg/__init__.py | 7 +- fHDHR/device/ssdp/__init__.py | 196 +++++++++++++++++--------------- fHDHR/device/ssdp/hdhr_ssdp.py | 51 ++++----- fHDHR/device/ssdp/rmg_ssdp.py | 51 ++++----- fHDHR/device/tuners/tuner.py | 9 +- fHDHR_web/__init__.py | 9 +- fHDHR_web/pages/cluster_html.py | 4 +- 11 files changed, 226 insertions(+), 188 deletions(-) create mode 100644 fHDHR/api/__init__.py diff --git a/data/internal_config/ssdp.json b/data/internal_config/ssdp.json index abe84b2..02cfdb0 100644 --- a/data/internal_config/ssdp.json +++ b/data/internal_config/ssdp.json @@ -5,10 +5,25 @@ "config_file": true, "config_web": false }, - "refresh_frequency":{ + "max_age":{ "value": 1800, "config_file": true, "config_web": false - } + }, + "proto":{ + "value": "ipv4", + "config_file": true, + "config_web": false + }, + "iface":{ + "value": "none", + "config_file": true, + "config_web": false + }, + "multicast_address":{ + "value": "none", + "config_file": true, + "config_web": false + } } } diff --git a/fHDHR/__init__.py b/fHDHR/__init__.py index a8e9384..5e40adc 100644 --- a/fHDHR/__init__.py +++ b/fHDHR/__init__.py @@ -2,6 +2,7 @@ from .originwrapper import OriginServiceWrapper from .device import fHDHR_Device +from .api import fHDHR_API_URLs import fHDHR.tools @@ -18,6 +19,8 @@ class fHDHR_INT_OBJ(): self.web = fHDHR.tools.WebReq() + self.api = fHDHR_API_URLs(settings) + class fHDHR_OBJ(): diff --git a/fHDHR/api/__init__.py b/fHDHR/api/__init__.py new file mode 100644 index 0000000..17aae97 --- /dev/null +++ b/fHDHR/api/__init__.py @@ -0,0 +1,36 @@ +import urllib.parse + + +class fHDHR_API_URLs(): + + def __init__(self, settings): + self.config = settings + + self.address = self.config.dict["fhdhr"]["address"] + self.discovery_address = self.config.dict["fhdhr"]["discovery_address"] + self.port = self.config.dict["fhdhr"]["port"] + + @property + def base(self): + if self.discovery_address: + return ('http://%s:%s' % self.discovery_address_tuple) + elif self.address == "0.0.0.0": + return ('http://%s:%s' % self.address_tuple) + else: + return ('http://%s:%s' % self.address_tuple) + + @property + def base_quoted(self): + return urllib.parse.quote(self.base) + + @property + def discovery_address_tuple(self): + return (self.discovery_address, int(self.port)) + + @property + def localhost_address_tuple(self): + return ("127.0.0.1", int(self.port)) + + @property + def address_tuple(self): + return (self.address, int(self.port)) diff --git a/fHDHR/device/cluster.py b/fHDHR/device/cluster.py index 3a6e629..4d5a5ab 100644 --- a/fHDHR/device/cluster.py +++ b/fHDHR/device/cluster.py @@ -1,4 +1,3 @@ -import urllib.parse from collections import OrderedDict @@ -10,14 +9,8 @@ class fHDHR_Cluster(): self.ssdp = ssdp self.friendlyname = self.fhdhr.config.dict["fhdhr"]["friendlyname"] - self.location = None - self.location_url = None - - if fhdhr.config.dict["fhdhr"]["discovery_address"]: - self.location = ('http://' + fhdhr.config.dict["fhdhr"]["discovery_address"] + ':' + - str(fhdhr.config.dict["fhdhr"]["port"])) - self.location_url = urllib.parse.quote(self.location) + if self.fhdhr.config.dict["fhdhr"]["discovery_address"]: self.startup_sync() def cluster(self): @@ -31,7 +24,7 @@ class fHDHR_Cluster(): "base_url": fhdhr_list[location]["base_url"], "name": fhdhr_list[location]["name"] } - if item_dict["base_url"] != self.location: + if item_dict["base_url"] != self.fhdhr.api.base: locations.append(item_dict) if len(locations): locations = sorted(locations, key=lambda i: i['name']) @@ -43,7 +36,7 @@ class fHDHR_Cluster(): cluster = self.fhdhr.db.get_fhdhr_value("cluster", "dict") or self.default_cluster() return_dict = {} for location in list(cluster.keys()): - if location != self.location: + if location != self.fhdhr.api.base: return_dict[location] = { "Joined": True } @@ -59,8 +52,8 @@ class fHDHR_Cluster(): def default_cluster(self): defdict = {} - defdict[self.location] = { - "base_url": self.location, + defdict[self.fhdhr.api.base] = { + "base_url": self.fhdhr.api.base, "name": self.friendlyname } return defdict @@ -73,13 +66,13 @@ class fHDHR_Cluster(): else: self.fhdhr.logger.info("Found %s clustered services." % str(len(list(cluster.keys())))) for location in list(cluster.keys()): - if location != self.location: + if location != self.fhdhr.api.base: self.fhdhr.logger.info("Checking Cluster Syncronization information from %s." % location) sync_url = location + "/api/cluster?method=get" try: sync_open = self.fhdhr.web.session.get(sync_url) retrieved_cluster = sync_open.json() - if self.location not in list(retrieved_cluster.keys()): + if self.fhdhr.api.base not in list(retrieved_cluster.keys()): return self.leave() except self.fhdhr.web.exceptions.ConnectionError: self.fhdhr.logger.error("Unreachable: " + location) @@ -91,9 +84,9 @@ class fHDHR_Cluster(): def disconnect(self): cluster = self.fhdhr.db.get_fhdhr_value("cluster", "dict") or self.default_cluster() for location in list(cluster.keys()): - if location != self.location: + if location != self.fhdhr.api.base: self.fhdhr.logger.info("Informing %s that I am departing the Cluster." % location) - sync_url = location + "/api/cluster?method=del&location=" + self.location + sync_url = location + "/api/cluster?method=del&location=" + self.fhdhr.api.base try: self.fhdhr.web.session.get(sync_url) except self.fhdhr.web.exceptions.ConnectionError: @@ -111,8 +104,8 @@ class fHDHR_Cluster(): def push_sync(self): cluster = self.fhdhr.db.get_fhdhr_value("cluster", "dict") or self.default_cluster() for location in list(cluster.keys()): - if location != self.location: - sync_url = location + "/api/cluster?method=sync&location=" + self.location_url + if location != self.fhdhr.api.base: + sync_url = location + "/api/cluster?method=sync&location=" + self.fhdhr.api.base_quoted try: self.fhdhr.web.session.get(sync_url) except self.fhdhr.web.exceptions.ConnectionError: diff --git a/fHDHR/device/epg/__init__.py b/fHDHR/device/epg/__init__.py index 4d7e817..2804730 100644 --- a/fHDHR/device/epg/__init__.py +++ b/fHDHR/device/epg/__init__.py @@ -36,12 +36,7 @@ class EPG(): if epg_method not in list(self.sleeptime.keys()): self.sleeptime[epg_method] = self.fhdhr.config.dict["epg"]["update_frequency"] - if self.fhdhr.config.dict["fhdhr"]["address"] == "0.0.0.0": - self.location = ('http://127.0.0.1:%s' % str(self.fhdhr.config.dict["fhdhr"]["port"])) - else: - self.location = ('http://%s:%s' % (self.fhdhr.config.dict["fhdhr"]["address"], str(self.fhdhr.config.dict["fhdhr"]["port"]))) - - self.epg_update_url = "%s/api/epg?method=update" % (self.location) + self.epg_update_url = "%s/api/epg?method=update" % (self.fhdhr.api.base) def clear_epg_cache(self, method=None): diff --git a/fHDHR/device/ssdp/__init__.py b/fHDHR/device/ssdp/__init__.py index ed317d8..c095325 100644 --- a/fHDHR/device/ssdp/__init__.py +++ b/fHDHR/device/ssdp/__init__.py @@ -15,79 +15,19 @@ class SSDPServer(): self.detect_method = fHDHR_Detect(fhdhr) - if (fhdhr.config.dict["fhdhr"]["discovery_address"] and - fhdhr.config.dict["ssdp"]["enabled"]): + if (self.fhdhr.config.dict["fhdhr"]["discovery_address"] and + self.fhdhr.config.dict["ssdp"]["enabled"]): + self.setup_ssdp() - self.sock = None - self.proto = "ipv4" - self.port = 1900 - self.iface = None - self.address = None - - allowed_protos = ("ipv4", "ipv6") - if self.proto not in allowed_protos: - raise ValueError("Invalid proto - expected one of {}".format(allowed_protos)) - - self.location = ('http://' + fhdhr.config.dict["fhdhr"]["discovery_address"] + ':' + - str(fhdhr.config.dict["fhdhr"]["port"]) + '/device.xml') - - self._iface = None - - if self.proto == "ipv4": - self._af_type = socket.AF_INET - self._broadcast_ip = "239.255.255.250" - self._address = (self._broadcast_ip, self.port) - self.bind_address = "0.0.0.0" - elif self.proto == "ipv6": - self._af_type = socket.AF_INET6 - self._broadcast_ip = "ff02::c" - self._address = (self._broadcast_ip, self.port, 0, 0) - self.bind_address = "::" - - self.broadcast_addy = "{}:{}".format(self._broadcast_ip, self.port) - - self.sock = socket.socket(self._af_type, socket.SOCK_DGRAM, socket.IPPROTO_UDP) - self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - - # Bind to specific interface - if self.iface is not None: - self.sock.setsockopt(socket.SOL_SOCKET, getattr(socket, "SO_BINDTODEVICE", 25), self.iface) - - # Subscribe to multicast address - if self.proto == "ipv4": - mreq = socket.inet_aton(self._broadcast_ip) - if self.address is not None: - mreq += socket.inet_aton(self.address) - else: - mreq += struct.pack(b"@I", socket.INADDR_ANY) - self.sock.setsockopt( - socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq, - ) - # Allow multicasts on loopback devices (necessary for testing) - self.sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 1) - elif self.proto == "ipv6": - # In IPv6 we use the interface index, not the address when subscribing to the group - mreq = socket.inet_pton(socket.AF_INET6, self._broadcast_ip) - if self.iface is not None: - iface_index = socket.if_nametoindex(self.iface) - # Send outgoing packets from the same interface - self.sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_IF, iface_index) - mreq += struct.pack(b"@I", iface_index) - else: - mreq += socket.inet_pton(socket.AF_INET6, "::") - self.sock.setsockopt( - socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mreq, - ) - self.sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_LOOP, 1) - self.sock.bind((self.bind_address, self.port)) + self.sock.bind((self.bind_address, 1900)) self.msearch_payload = self.create_msearch_payload() - self.rmg_ssdp = RMG_SSDP(fhdhr, self._broadcast_ip) - self.hdhr_ssdp = HDHR_SSDP(fhdhr, self._broadcast_ip) + self.max_age = int(fhdhr.config.dict["ssdp"]["max_age"]) + self.age_time = None - self.refresh = int(fhdhr.config.dict["ssdp"]["refresh_frequency"]) - self.refresh_last = None + self.rmg_ssdp = RMG_SSDP(fhdhr, self.broadcast_ip, self.max_age) + self.hdhr_ssdp = HDHR_SSDP(fhdhr, self.broadcast_ip, self.max_age) self.do_alive() self.m_search() @@ -95,17 +35,17 @@ class SSDPServer(): def do_alive(self, forcealive=False): send_alive = False - if not self.refresh_last: + if not self.age_time: send_alive = True elif forcealive: send_alive = True - elif time.time() >= (self.refresh_last + self.refresh): + elif time.time() >= (self.age_time + self.max_age): send_alive = True if send_alive: self.fhdhr.logger.info("Sending Alive message to network.") - self.do_notify(('239.255.255.250', 1900)) - self.refresh_last = time.time() + self.do_notify(self.broadcase_address_tuple) + self.age_time = time.time() def do_notify(self, address): @@ -118,11 +58,11 @@ class SSDPServer(): rmg_notify = self.rmg_ssdp.get() notify_list.append(rmg_notify) - for notify in notify_list: + for notifydata in notify_list: - self.fhdhr.logger.debug("Created {}".format(notify)) + self.fhdhr.logger.debug("Created {}".format(notifydata)) try: - self.sock.sendto(notify, address) + self.sock.sendto(notifydata, address) except OSError as e: # Most commonly: We received a multicast from an IP not in our subnet self.fhdhr.logger.debug("Unable to send NOTIFY: %s" % e) @@ -157,12 +97,12 @@ class SSDPServer(): self.fhdhr.logger.debug("NOTIFY data: {}".format(headers)) try: if headers["server"].startswith("fHDHR"): - if headers["location"] != self.location: - savelocation = headers["location"].split("/device.xml")[0] - if savelocation.endswith("/hdhr"): - savelocation = savelocation.replace("/hdhr", '') - elif savelocation.endswith("/rmg"): - savelocation = savelocation.replace("/rmg", '') + savelocation = headers["location"].split("/device.xml")[0] + if savelocation.endswith("/hdhr"): + savelocation = savelocation.replace("/hdhr", '') + elif savelocation.endswith("/rmg"): + savelocation = savelocation.replace("/rmg", '') + if savelocation != self.fhdhr.api.base: self.detect_method.set(savelocation) except KeyError: return @@ -171,21 +111,25 @@ class SSDPServer(): def m_search(self): data = self.msearch_payload - self.sock.sendto(data, self._address) + self.sock.sendto(data, self.broadcase_address_tuple) def create_msearch_payload(self): - data = ( - "M-SEARCH * HTTP/1.1\r\n" - "HOST:{}\r\n" - 'MAN: "ssdp:discover"\r\n' - "ST:{}\r\n" - "MX:{}\r\n" - ).format( - self.broadcast_addy, - "ssdp:all", - 1 - ) + + data = '' + data_command = "M-SEARCH * HTTP/1.1" + + data_dict = { + "HOST": "%s:%s" % (self.broadcast_ip, 1900), + "MAN": "ssdp:discover", + "ST": "ssdp:all", + "MX": 1, + } + + data += "%s\r\n" % data_command + for data_key in list(data_dict.keys()): + data += "%s:%s\r\n" % (data_key, data_dict[data_key]) data += "\r\n" + return data.encode("utf-8") def run(self): @@ -196,3 +140,69 @@ class SSDPServer(): self.do_alive() except KeyboardInterrupt: self.sock.close() + + def setup_ssdp(self): + self.sock = None + + self.proto = self.setup_proto() + self.iface = self.fhdhr.config.dict["ssdp"]["iface"] + self.address = self.fhdhr.config.dict["ssdp"]["multicast_address"] + self.setup_addressing() + + self.sock = socket.socket(self.af_type, socket.SOCK_DGRAM, socket.IPPROTO_UDP) + self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + + self.setup_interface() + + self.setup_multicasting() + + def setup_proto(self): + proto = self.fhdhr.config.dict["ssdp"]["proto"] + allowed_protos = ("ipv4", "ipv6") + if proto not in allowed_protos: + raise ValueError("Invalid proto - expected one of {}".format(allowed_protos)) + return proto + + def setup_addressing(self): + if self.proto == "ipv4": + self.af_type = socket.AF_INET + self.broadcast_ip = "239.255.255.250" + self.broadcase_address_tuple = (self.broadcast_ip, 1900) + self.bind_address = "0.0.0.0" + elif self.proto == "ipv6": + self.af_type = socket.AF_INET6 + self.broadcast_ip = "ff02::c" + self.broadcast_address_tuple = (self.broadcast_ip, 1900, 0, 0) + self.bind_address = "::" + + def setup_interface(self): + # Bind to specific interface + if self.iface is not None: + self.sock.setsockopt(socket.SOL_SOCKET, getattr(socket, "SO_BINDTODEVICE", 25), self.iface) + + def setup_multicasting(self): + # Subscribe to multicast address + if self.proto == "ipv4": + mreq = socket.inet_aton(self.broadcast_ip) + if self.address is not None: + mreq += socket.inet_aton(self.address) + else: + mreq += struct.pack(b"@I", socket.INADDR_ANY) + self.sock.setsockopt( + socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) + # Allow multicasts on loopback devices (necessary for testing) + self.sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 1) + elif self.proto == "ipv6": + # In IPv6 we use the interface index, not the address when subscribing to the group + mreq = socket.inet_pton(socket.AF_INET6, self.broadcast_ip) + if self.iface is not None: + iface_index = socket.if_nametoindex(self.iface) + # Send outgoing packets from the same interface + self.sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_IF, iface_index) + mreq += struct.pack(b"@I", iface_index) + else: + mreq += socket.inet_pton(socket.AF_INET6, "::") + self.sock.setsockopt( + socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mreq, + ) + self.sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_LOOP, 1) diff --git a/fHDHR/device/ssdp/hdhr_ssdp.py b/fHDHR/device/ssdp/hdhr_ssdp.py index 7f8cb11..b9f4e36 100644 --- a/fHDHR/device/ssdp/hdhr_ssdp.py +++ b/fHDHR/device/ssdp/hdhr_ssdp.py @@ -2,43 +2,38 @@ class HDHR_SSDP(): - def __init__(self, fhdhr, _broadcast_ip): + def __init__(self, fhdhr, broadcast_ip, max_age): self.fhdhr = fhdhr self.ssdp_content = None - self._broadcast_ip = _broadcast_ip - self.nt = 'urn:schemas-upnp-org:device:MediaServer:1' - self.usn = 'uuid:' + fhdhr.config.dict["main"]["uuid"] + '::' + self.nt - self.server = 'fHDHR/%s UPnP/1.0' % fhdhr.version - self.location = ('http://' + fhdhr.config.dict["fhdhr"]["discovery_address"] + ':' + - str(fhdhr.config.dict["fhdhr"]["port"]) + '/device.xml') - self.al = self.location - self.max_age = 1800 + self.broadcast_ip = broadcast_ip + self.device_xml_path = '/device.xml' + + self.max_age = max_age def get(self): if self.ssdp_content: return self.ssdp_content.encode("utf-8") - data = ( - "NOTIFY * HTTP/1.1\r\n" - "HOST:{}\r\n" - "NT:{}\r\n" - "NTS:ssdp:alive\r\n" - "USN:{}\r\n" - "SERVER:{}\r\n" - ).format( - self._broadcast_ip, - self.nt, - self.usn, - self.server - ) - if self.location is not None: - data += "LOCATION:{}\r\n".format(self.location) - if self.al is not None: - data += "AL:{}\r\n".format(self.al) - if self.max_age is not None: - data += "Cache-Control:max-age={}\r\n".format(self.max_age) + data = '' + data_command = "NOTIFY * HTTP/1.1" + + data_dict = { + "HOST": "%s:%s" % (self.broadcast_ip, 1900), + "NT": 'urn:schemas-upnp-org:device:MediaServer:1', + "NTS": "ssdp:alive", + "USN": 'uuid:%s::%s' % (self.fhdhr.config.dict["main"]["uuid"], 'urn:schemas-upnp-org:device:MediaServer:1'), + "SERVER": 'fHDHR/%s UPnP/1.0' % self.fhdhr.version, + "LOCATION": "%s%s" % (self.fhdhr.api.base, self.device_xml_path), + "AL": "%s%s" % (self.fhdhr.api.base, self.device_xml_path), + "Cache-Control:max-age=": self.max_age + } + + data += "%s\r\n" % data_command + for data_key in list(data_dict.keys()): + data += "%s:%s\r\n" % (data_key, data_dict[data_key]) data += "\r\n" + self.ssdp_content = data return data.encode("utf-8") diff --git a/fHDHR/device/ssdp/rmg_ssdp.py b/fHDHR/device/ssdp/rmg_ssdp.py index 31d6466..3cf9a4a 100644 --- a/fHDHR/device/ssdp/rmg_ssdp.py +++ b/fHDHR/device/ssdp/rmg_ssdp.py @@ -2,43 +2,38 @@ class RMG_SSDP(): - def __init__(self, fhdhr, _broadcast_ip): + def __init__(self, fhdhr, broadcast_ip, max_age): self.fhdhr = fhdhr self.ssdp_content = None - self._broadcast_ip = _broadcast_ip - self.nt = 'urn:schemas-upnp-org:device-1-0' - self.usn = 'uuid:' + fhdhr.config.dict["main"]["uuid"] + '::' + self.nt - self.server = 'fHDHR/%s UPnP/1.0' % fhdhr.version - self.location = ('http://' + fhdhr.config.dict["fhdhr"]["discovery_address"] + ':' + - str(fhdhr.config.dict["fhdhr"]["port"]) + '/device.xml') - self.al = self.location - self.max_age = 1800 + self.broadcast_ip = broadcast_ip + self.device_xml_path = '/device.xml' + + self.max_age = max_age def get(self): if self.ssdp_content: return self.ssdp_content.encode("utf-8") - data = ( - "NOTIFY * HTTP/1.1\r\n" - "HOST:{}\r\n" - "NT:{}\r\n" - "NTS:ssdp:alive\r\n" - "USN:{}\r\n" - "SERVER:{}\r\n" - ).format( - self._broadcast_ip, - self.nt, - self.usn, - self.server - ) - if self.location is not None: - data += "LOCATION:{}\r\n".format(self.location) - if self.al is not None: - data += "AL:{}\r\n".format(self.al) - if self.max_age is not None: - data += "Cache-Control:max-age={}\r\n".format(self.max_age) + data = '' + data_command = "NOTIFY * HTTP/1.1" + + data_dict = { + "HOST": "%s:%s" % (self.broadcast_ip, 1900), + "NT": 'urn:schemas-upnp-org:device-1-0', + "NTS": "ssdp:alive", + "USN": 'uuid:%s::%s' % (self.fhdhr.config.dict["main"]["uuid"], 'urn:schemas-upnp-org:device-1-0'), + "SERVER": 'fHDHR/%s UPnP/1.0' % self.fhdhr.version, + "LOCATION": "%s%s" % (self.fhdhr.api.base, self.device_xml_path), + "AL": "%s%s" % (self.fhdhr.api.base, self.device_xml_path), + "Cache-Control:max-age=": self.max_age + } + + data += "%s\r\n" % data_command + for data_key in list(data_dict.keys()): + data += "%s:%s\r\n" % (data_key, data_dict[data_key]) data += "\r\n" + self.ssdp_content = data return data.encode("utf-8") diff --git a/fHDHR/device/tuners/tuner.py b/fHDHR/device/tuners/tuner.py index 09c7421..d1aa593 100644 --- a/fHDHR/device/tuners/tuner.py +++ b/fHDHR/device/tuners/tuner.py @@ -18,13 +18,8 @@ class Tuner(): self.tuner_lock = threading.Lock() self.set_off_status() - if fhdhr.config.dict["fhdhr"]["address"] == "0.0.0.0": - self.location = ('http://127.0.0.1:%s' % str(fhdhr.config.dict["fhdhr"]["port"])) - else: - self.location = ('http://%s:%s' % (fhdhr.config.dict["fhdhr"]["address"], str(fhdhr.config.dict["fhdhr"]["port"]))) - - self.chanscan_url = "%s/api/channels?method=scan" % (self.location) - self.close_url = "%s/api/tuners?method=close&tuner=%s" % (self.location, str(self.number)) + self.chanscan_url = "%s/api/channels?method=scan" % (self.fhdhr.api.base) + self.close_url = "%s/api/tuners?method=close&tuner=%s" % (self.fhdhr.api.base, str(self.number)) def channel_scan(self): if self.tuner_lock.locked(): diff --git a/fHDHR_web/__init__.py b/fHDHR_web/__init__.py index 86b9742..7b01fdb 100644 --- a/fHDHR_web/__init__.py +++ b/fHDHR_web/__init__.py @@ -89,10 +89,11 @@ class fHDHR_HTTP_Server(): self.app.add_url_rule(endpoint, endpoint_name, handler, methods=methods) def run(self): - self.http = WSGIServer(( - self.fhdhr.config.dict["fhdhr"]["address"], - int(self.fhdhr.config.dict["fhdhr"]["port"]) - ), self.app.wsgi_app, log=self.fhdhr.logger) + + self.http = WSGIServer(self.fhdhr.api.address_tuple, + self.app.wsgi_app, + log=self.fhdhr.logger) + try: self.http.serve_forever() except KeyboardInterrupt: diff --git a/fHDHR_web/pages/cluster_html.py b/fHDHR_web/pages/cluster_html.py index 95fdb21..cc26a12 100644 --- a/fHDHR_web/pages/cluster_html.py +++ b/fHDHR_web/pages/cluster_html.py @@ -10,9 +10,9 @@ class Cluster_HTML(): self.fhdhr = fhdhr self.location_dict = { "name": self.fhdhr.config.dict["fhdhr"]["friendlyname"], - "location": self.fhdhr.device.cluster.location, + "location": self.fhdhr.api.base, "joined": "N/A", - "url_query": self.fhdhr.device.cluster.location_url + "url_query": self.fhdhr.api.base_quoted } def __call__(self, *args): From f8429883a631cee97fcb7bf008fea87ed24487b7 Mon Sep 17 00:00:00 2001 From: deathbybandaid Date: Tue, 8 Dec 2020 13:19:50 -0500 Subject: [PATCH 8/8] Add Web Version --- fHDHR/cli/run.py | 6 +++--- fHDHR/config/__init__.py | 5 ++++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/fHDHR/cli/run.py b/fHDHR/cli/run.py index 6a90246..49c5697 100644 --- a/fHDHR/cli/run.py +++ b/fHDHR/cli/run.py @@ -31,10 +31,10 @@ def build_args_parser(): return parser.parse_args() -def get_configuration(args, script_dir, origin): +def get_configuration(args, script_dir, origin, fHDHR_web): if not os.path.isfile(args.cfg): raise fHDHR.exceptions.ConfigurationNotFound(filename=args.cfg) - return fHDHR.config.Config(args.cfg, script_dir, origin) + return fHDHR.config.Config(args.cfg, script_dir, origin, fHDHR_web) def run(settings, logger, db, script_dir, fHDHR_web, origin, alternative_epg): @@ -84,7 +84,7 @@ def start(args, script_dir, fHDHR_web, origin, alternative_epg): """Get Configuration for fHDHR and start""" try: - settings = get_configuration(args, script_dir, origin) + settings = get_configuration(args, script_dir, origin, fHDHR_web) except fHDHR.exceptions.ConfigurationError as e: print(e) return ERR_CODE_NO_RESTART diff --git a/fHDHR/config/__init__.py b/fHDHR/config/__init__.py index e0784f9..02483ca 100644 --- a/fHDHR/config/__init__.py +++ b/fHDHR/config/__init__.py @@ -15,8 +15,9 @@ from fHDHR.tools import isint, isfloat, is_arithmetic, is_docker class Config(): - def __init__(self, filename, script_dir, origin): + def __init__(self, filename, script_dir, origin, fHDHR_web): self.origin = origin + self.fHDHR_web = fHDHR_web self.internal = {} self.conf_default = {} @@ -67,6 +68,8 @@ class Config(): self.internal["versions"]["fHDHR"] = fHDHR_VERSION + self.internal["versions"]["fHDHR_web"] = self.fHDHR_web.fHDHR_web_VERSION + self.internal["versions"][self.origin.ORIGIN_NAME] = self.origin.ORIGIN_VERSION self.internal["versions"]["Python"] = sys.version