diff --git a/config.all.ini b/config.all.ini index be054e9..b0ccafc 100644 --- a/config.all.ini +++ b/config.all.ini @@ -24,7 +24,7 @@ # update_frequency = 43200 [ffmpeg] -# ffmpeg_path = ffmpeg +# path = ffmpeg # bytes_per_read = 1152000 [direct_stream] diff --git a/data/internal_config/fhdhr.ini b/data/internal_config/fhdhr.ini deleted file mode 100644 index 4e11cb0..0000000 --- a/data/internal_config/fhdhr.ini +++ /dev/null @@ -1,36 +0,0 @@ -[main] -uuid = -cache_dir = -thread_method = multiprocessing - -[fhdhr] -address = 0.0.0.0 -discovery_address = 0.0.0.0 -port = 5004 -reporting_manufacturer = BoronDust -reporting_model = fHDHR -reporting_firmware_ver = 20201001 -reporting_tuner_type = Antenna -device_auth = fHDHR -require_auth = False - -[epg] -images = pass - -[ffmpeg] -ffmpeg_path = ffmpeg -bytes_per_read = 1152000 - -[vlc] -vlc_path = cvlc -bytes_per_read = 1152000 - -[direct_stream] -chunksize = 1048576 - -[logging] -level = WARNING - -[database] -type = sqlite -driver = None diff --git a/data/internal_config/fhdhr.json b/data/internal_config/fhdhr.json new file mode 100644 index 0000000..1ead531 --- /dev/null +++ b/data/internal_config/fhdhr.json @@ -0,0 +1,148 @@ +{ + "main":{ + "uuid":{ + "value": "none", + "config_file": true, + "config_web": false + }, + "cache_dir":{ + "value": "none", + "config_file": true, + "config_web": true + }, + "thread_method":{ + "value": "multiprocessing", + "config_file": true, + "config_web": true + } + }, + "fhdhr":{ + "address":{ + "value": "0.0.0.0", + "config_file": true, + "config_web": true + }, + "discovery_address":{ + "value": "none", + "config_file": true, + "config_web": true + }, + "port":{ + "value": 5004, + "config_file": true, + "config_web": true + }, + "reporting_manufacturer":{ + "value": "BoronDust", + "config_file": true, + "config_web": true + }, + "reporting_model":{ + "value": "fHDHR", + "config_file": true, + "config_web": true + }, + "reporting_firmware_ver":{ + "value": "20201001", + "config_file": true, + "config_web": true + }, + "reporting_tuner_type":{ + "value": "Antenna", + "config_file": true, + "config_web": true + }, + "device_auth":{ + "value": "fHDHR", + "config_file": true, + "config_web": true + }, + "require_auth":{ + "value": false, + "config_file": true, + "config_web": true + } + }, + "epg":{ + "images":{ + "value": "pass", + "config_file": true, + "config_web": true + } + }, + "ffmpeg":{ + "path":{ + "value": "ffmpeg", + "config_file": true, + "config_web": true + }, + "bytes_per_read":{ + "value": 1152000, + "config_file": true, + "config_web": true + } + }, + "vlc":{ + "path":{ + "value": "cvlc", + "config_file": true, + "config_web": true + }, + "bytes_per_read":{ + "value": 1152000, + "config_file": true, + "config_web": true + } + }, + "direct_stream":{ + "chunksize":{ + "value": 1048576, + "config_file": true, + "config_web": true + } + }, + "logging":{ + "level":{ + "value": "WARNING", + "config_file": true, + "config_web": true + } + }, + "database":{ + "type":{ + "value": "sqlite", + "config_file": true, + "config_web": false + }, + "driver":{ + "value": "none", + "config_file": true, + "config_web": false + }, + "user":{ + "value": "none", + "config_file": true, + "config_web": false + }, + "pass":{ + "value": "none", + "config_file": true, + "config_web": false + }, + "host":{ + "value": "none", + "config_file": true, + "config_web": false + }, + "port":{ + "value": "none", + "config_file": true, + "config_web": false + }, + "name":{ + "value": "none", + "config_file": true, + "config_web": false + } + } +} diff --git a/data/internal_config/serviceconf.ini b/data/internal_config/serviceconf.ini deleted file mode 100644 index d8be804..0000000 --- a/data/internal_config/serviceconf.ini +++ /dev/null @@ -1,25 +0,0 @@ -[main] -servicename = NextPVR -dictpopname = nextpvr -reponame = fHDHR_NextPVR -required = nextpvr/pin -valid_epg_methods = None,blocks,origin,zap2it - -[fhdhr] -friendlyname = fHDHR-NextPVR -stream_type = direct -tuner_count = 4 -reporting_firmware_name = fHDHR_NextPVR - -[epg] -method = origin -update_frequency = 43200 - -[nextpvr] -address = localhost -port = 8866 -ssl = False -pin = -weight = 300 -epg_update_frequency = 43200 -sid = diff --git a/data/internal_config/serviceconf.json b/data/internal_config/serviceconf.json new file mode 100644 index 0000000..cd02536 --- /dev/null +++ b/data/internal_config/serviceconf.json @@ -0,0 +1,91 @@ +{ + "main":{ + "servicename":{ + "value": "NextPVR", + "config_file": false, + "config_web": false + }, + "dictpopname":{ + "value": "nextpvr", + "config_file": false, + "config_web": false + }, + "reponame":{ + "value": "fHDHR_NextPVR", + "config_file": false, + "config_web": false + }, + "valid_epg_methods":{ + "value": "None,blocks,origin,zap2it", + "config_file": false, + "config_web": false + }, + "required":{ + "value": "nextpvr/pin", + "config_file": false, + "config_web": false + } + }, + "fhdhr":{ + "friendlyname":{ + "value": "fHDHR-NextPVR", + "config_file": true, + "config_web": true + }, + "stream_type":{ + "value": "direct", + "config_file": true, + "config_web": true + }, + "tuner_count":{ + "value": 4, + "config_file": true, + "config_web": true + }, + "reporting_firmware_name":{ + "value": "fHDHR_NextPVR", + "config_file": true, + "config_web": true + } + }, + "epg":{ + "method":{ + "value": "origin", + "config_file": true, + "config_web": true + }, + "update_frequency":{ + "value": 43200, + "config_file": true, + "config_web": true + } + }, + "nextpvr":{ + "address":{ + "value": "localhost", + "config_file": true, + "config_web": true + }, + "port":{ + "value": 8866, + "config_file": true, + "config_web": true + }, + "ssl":{ + "value": false, + "config_file": true, + "config_web": true + }, + "pin":{ + "value": "none", + "config_file": true, + "config_web": true, + "config_web_hidden": true + }, + "sid":{ + "value": "none", + "config_file": true, + "config_web": false + } + } +} diff --git a/data/internal_config/zap2it.ini b/data/internal_config/zap2it.ini deleted file mode 100644 index 9174a38..0000000 --- a/data/internal_config/zap2it.ini +++ /dev/null @@ -1,13 +0,0 @@ -[zap2it] -delay = 5 -postalcode = -affiliate_id = gapzap -country = USA -device = - -headendid = lineupId -isoverride = True -languagecode = en -pref = -timespan = 6 -timezone = -userid = - diff --git a/data/internal_config/zap2it.json b/data/internal_config/zap2it.json new file mode 100644 index 0000000..fcf5a6a --- /dev/null +++ b/data/internal_config/zap2it.json @@ -0,0 +1,64 @@ +{ + "zap2it":{ + "delay":{ + "value": 5, + "config_file": true, + "config_web": false + }, + "postalcode":{ + "value": "none", + "config_file": true, + "config_web": false + }, + "affiliate_id":{ + "value": "gapzap", + "config_file": true, + "config_web": false + }, + "country":{ + "value": "USA", + "config_file": true, + "config_web": false + }, + "device":{ + "value": "-", + "config_file": true, + "config_web": false + }, + "headendid":{ + "value": "lineupId", + "config_file": true, + "config_web": false + }, + "isoverride":{ + "value": true, + "config_file": true, + "config_web": false + }, + "languagecode":{ + "value": "en", + "config_file": true, + "config_web": false + }, + "pref":{ + "value": "none", + "config_file": true, + "config_web": false + }, + "timespan":{ + "value": 6, + "config_file": true, + "config_web": false + }, + "timezone":{ + "value": "none", + "config_file": true, + "config_web": false + }, + "userid":{ + "value": "-", + "config_file": true, + "config_web": false + } + } +} diff --git a/data/www/templates/base.html b/data/www/templates/base.html index ec3dab1..1418272 100644 --- a/data/www/templates/base.html +++ b/data/www/templates/base.html @@ -24,6 +24,7 @@ + xmltv m3u diff --git a/data/www/templates/settings.html b/data/www/templates/settings.html new file mode 100644 index 0000000..6719fa1 --- /dev/null +++ b/data/www/templates/settings.html @@ -0,0 +1,60 @@ +{% extends "base.html" %} + +{% block content %} + +

fHDHR Settings

+ +

Settings will require a manual restart.

+ + {% for config_section in list(web_settings_dict.keys()) %} + + {% if config_section == "origin" %} +

{{ fhdhr.config.dict["main"]["dictpopname"] }}

+ {% else %} +

{{ config_section }}

+ {% endif %} + + + + + + + + + + + {% for config_item in list(web_settings_dict[config_section].keys()) %} + + + + + + + + + + + {% if web_settings_dict[config_section][config_item]["hide"] %} + + {% else %} + + {% endif %} + + + + + + + + + + + + + + {% endfor %} +
Config NameConfig Default ValueConfig ValueUpdateReset
{{ config_item }}{{ web_settings_dict[config_section][config_item]["value_default"] }}
+ + {% endfor %} + +{% endblock %} diff --git a/fHDHR/config/__init__.py b/fHDHR/config/__init__.py index eb1ffe6..8d0d14e 100644 --- a/fHDHR/config/__init__.py +++ b/fHDHR/config/__init__.py @@ -5,6 +5,7 @@ import pathlib import logging import subprocess import platform +import json import fHDHR.exceptions from fHDHR.tools import isint, isfloat, is_arithmetic, is_docker @@ -13,42 +14,148 @@ from fHDHR.tools import isint, isfloat, is_arithmetic, is_docker class Config(): def __init__(self, filename, script_dir): + self.internal = {} + self.conf_default = {} self.dict = {} self.config_file = filename - self.parser = configparser.RawConfigParser(allow_no_value=True) - - self.load_defaults(script_dir) - - print("Loading Configuration File: " + str(self.config_file)) - self.read_config(self.config_file) + self.initial_load(script_dir) self.config_verification() - def load_defaults(self, script_dir): + def initial_load(self, script_dir): data_dir = pathlib.Path(script_dir).joinpath('data') www_dir = pathlib.Path(data_dir).joinpath('www') - self.dict["filedir"] = { + self.internal["paths"] = { "script_dir": script_dir, "data_dir": data_dir, - "cache_dir": pathlib.Path(data_dir).joinpath('cache'), "internal_config": pathlib.Path(data_dir).joinpath('internal_config'), "www_dir": www_dir, - "www_images_dir": pathlib.Path(www_dir).joinpath('images'), "www_templates_dir": pathlib.Path(www_dir).joinpath('templates'), "font": pathlib.Path(data_dir).joinpath('garamond.ttf'), - "favicon": pathlib.Path(data_dir).joinpath('favicon.ico'), - "epg_cache": {}, } - for conffile in os.listdir(self.dict["filedir"]["internal_config"]): - conffilepath = os.path.join(self.dict["filedir"]["internal_config"], conffile) - if str(conffilepath).endswith(".ini"): - self.read_config(conffilepath) + for conffile in os.listdir(self.internal["paths"]["internal_config"]): + conffilepath = os.path.join(self.internal["paths"]["internal_config"], conffile) + if str(conffilepath).endswith(".json"): + self.read_json_config(conffilepath) - def read_config(self, conffilepath): + print("Loading Configuration File: " + str(self.config_file)) + self.read_ini_config(self.config_file) + + self.load_versions() + + def load_versions(self): + + self.internal["versions"] = { + "opersystem": None, + "isdocker": False, + "ffmpeg": "N/A", + "vlc": "N/A" + } + + opersystem = platform.system() + self.internal["versions"]["opersystem"] = opersystem + if opersystem in ["Linux", "Darwin"]: + # Linux/Mac + if os.getuid() == 0 or os.geteuid() == 0: + print('Warning: Do not run fHDHR with root privileges.') + elif opersystem in ["Windows"]: + # Windows + if os.environ.get("USERNAME") == "Administrator": + print('Warning: Do not run fHDHR as Administrator.') + else: + print("Uncommon Operating System, use at your own risk.") + + isdocker = is_docker() + self.internal["versions"]["isdocker"] = isdocker + + if self.dict["fhdhr"]["stream_type"] == "ffmpeg": + try: + ffmpeg_command = [self.dict["ffmpeg"]["path"], + "-version", + "pipe:stdout" + ] + + ffmpeg_proc = subprocess.Popen(ffmpeg_command, stdout=subprocess.PIPE) + ffmpeg_version = ffmpeg_proc.stdout.read() + ffmpeg_proc.terminate() + ffmpeg_proc.communicate() + ffmpeg_version = ffmpeg_version.decode().split("version ")[1].split(" ")[0] + except FileNotFoundError: + ffmpeg_version = "Missing" + print("Failed to find ffmpeg.") + self.internal["versions"]["ffmpeg"] = ffmpeg_version + + if self.dict["fhdhr"]["stream_type"] == "vlc": + try: + vlc_command = [self.dict["vlc"]["path"], + "--version", + "pipe:stdout" + ] + + vlc_proc = subprocess.Popen(vlc_command, stdout=subprocess.PIPE) + vlc_version = vlc_proc.stdout.read() + vlc_proc.terminate() + vlc_proc.communicate() + vlc_version = vlc_version.decode().split("version ")[1].split('\n')[0] + except FileNotFoundError: + vlc_version = "Missing" + print("Failed to find vlc.") + self.internal["versions"]["vlc"] = vlc_version + + def read_json_config(self, conffilepath): + with open(conffilepath, 'r') as jsonconf: + confimport = json.load(jsonconf) + for section in list(confimport.keys()): + + if section not in self.dict.keys(): + self.dict[section] = {} + + if section not in self.conf_default.keys(): + self.conf_default[section] = {} + + for key in list(confimport[section].keys()): + + if key not in list(self.conf_default[section].keys()): + self.conf_default[section][key] = {} + + confvalue = confimport[section][key]["value"] + if isint(confvalue): + confvalue = int(confvalue) + elif isfloat(confvalue): + confvalue = float(confvalue) + elif is_arithmetic(confvalue): + confvalue = eval(confvalue) + elif "," in confvalue: + confvalue = confvalue.split(",") + elif str(confvalue).lower() in ["none"]: + confvalue = None + elif str(confvalue).lower() in ["false"]: + confvalue = False + elif str(confvalue).lower() in ["true"]: + confvalue = True + + self.dict[section][key] = confvalue + + self.conf_default[section][key]["value"] = confvalue + + for config_option in ["config_web_hidden", "config_file", "config_web"]: + if config_option not in list(confimport[section][key].keys()): + config_option_value = False + else: + config_option_value = confimport[section][key][config_option] + if str(config_option_value).lower() in ["none"]: + config_option_value = None + elif str(config_option_value).lower() in ["false"]: + config_option_value = False + elif str(config_option_value).lower() in ["true"]: + config_option_value = True + self.conf_default[section][key][config_option] = config_option_value + + def read_ini_config(self, conffilepath): config_handler = configparser.ConfigParser() config_handler.read(conffilepath) for each_section in config_handler.sections(): @@ -57,7 +164,9 @@ class Config(): for (each_key, each_val) in config_handler.items(each_section): if not each_val: each_val = None - elif each_val.lower() in ["none", "false"]: + elif each_val.lower() in ["none"]: + each_val = None + elif each_val.lower() in ["false"]: each_val = False elif each_val.lower() in ["true"]: each_val = True @@ -69,7 +178,15 @@ class Config(): each_val = eval(each_val) elif "," in each_val: each_val = each_val.split(",") - self.dict[each_section.lower()][each_key.lower()] = each_val + + import_val = True + if each_section in list(self.conf_default.keys()): + if each_key in list(self.conf_default[each_section].keys()): + if not self.conf_default[each_section][each_key]["config_file"]: + import_val = False + + if import_val: + self.dict[each_section.lower()][each_key.lower()] = each_val def write(self, section, key, value): if section == self.dict["main"]["dictpopname"]: @@ -126,95 +243,26 @@ class Config(): raise fHDHR.exceptions.ConfigurationError("Invalid EPG Method. Exiting...") self.dict["epg"]["def_method"] = self.dict["epg"]["method"][0] - # generate UUID here for when we are not using docker if not self.dict["main"]["uuid"]: - # from https://pynative.com/python-generate-random-string/ - # create a string that wouldn't be a real device uuid for self.dict["main"]["uuid"] = ''.join(random.choice("hijklmnopqrstuvwxyz") for i in range(8)) self.write('main', 'uuid', self.dict["main"]["uuid"]) if self.dict["main"]["cache_dir"]: if not pathlib.Path(self.dict["main"]["cache_dir"]).is_dir(): raise fHDHR.exceptions.ConfigurationError("Invalid Cache Directory. Exiting...") - self.dict["filedir"]["cache_dir"] = pathlib.Path(self.dict["main"]["cache_dir"]) - cache_dir = self.dict["filedir"]["cache_dir"] + self.internal["paths"]["cache_dir"] = pathlib.Path(self.dict["main"]["cache_dir"]) + cache_dir = self.internal["paths"]["cache_dir"] logs_dir = pathlib.Path(cache_dir).joinpath('logs') - self.dict["filedir"]["logs_dir"] = logs_dir + self.internal["paths"]["logs_dir"] = logs_dir if not logs_dir.is_dir(): logs_dir.mkdir() self.dict["database"]["path"] = pathlib.Path(cache_dir).joinpath('fhdhr.db') - for epg_method in self.dict["main"]["valid_epg_methods"]: - if epg_method and epg_method != "None": - epg_cache_dir = pathlib.Path(cache_dir).joinpath(epg_method) - if not epg_cache_dir.is_dir(): - epg_cache_dir.mkdir() - if epg_method not in list(self.dict["filedir"]["epg_cache"].keys()): - self.dict["filedir"]["epg_cache"][epg_method] = {} - self.dict["filedir"]["epg_cache"][epg_method]["top"] = epg_cache_dir - epg_web_cache_dir = pathlib.Path(epg_cache_dir).joinpath("web_cache") - if not epg_web_cache_dir.is_dir(): - epg_web_cache_dir.mkdir() - self.dict["filedir"]["epg_cache"][epg_method]["web_cache"] = epg_web_cache_dir - self.dict["filedir"]["epg_cache"][epg_method]["epg_json"] = pathlib.Path(epg_cache_dir).joinpath('epg.json') - if self.dict["fhdhr"]["stream_type"] not in ["direct", "ffmpeg", "vlc"]: raise fHDHR.exceptions.ConfigurationError("Invalid stream type. Exiting...") - opersystem = platform.system() - self.dict["main"]["opersystem"] = opersystem - if opersystem in ["Linux", "Darwin"]: - # Linux/Mac - if os.getuid() == 0 or os.geteuid() == 0: - print('Warning: Do not run fHDHR with root privileges.') - elif opersystem in ["Windows"]: - # Windows - if os.environ.get("USERNAME") == "Administrator": - print('Warning: Do not run fHDHR as Administrator.') - else: - print("Uncommon Operating System, use at your own risk.") - - isdocker = is_docker() - self.dict["main"]["isdocker"] = isdocker - - if self.dict["fhdhr"]["stream_type"] == "ffmpeg": - try: - ffmpeg_command = [self.dict["ffmpeg"]["ffmpeg_path"], - "-version", - "pipe:stdout" - ] - - ffmpeg_proc = subprocess.Popen(ffmpeg_command, stdout=subprocess.PIPE) - ffmpeg_version = ffmpeg_proc.stdout.read() - ffmpeg_proc.terminate() - ffmpeg_proc.communicate() - ffmpeg_version = ffmpeg_version.decode().split("version ")[1].split(" ")[0] - except FileNotFoundError: - ffmpeg_version = None - self.dict["ffmpeg"]["version"] = ffmpeg_version - else: - self.dict["ffmpeg"]["version"] = "N/A" - - if self.dict["fhdhr"]["stream_type"] == "vlc": - try: - vlc_command = [self.dict["vlc"]["vlc_path"], - "--version", - "pipe:stdout" - ] - - vlc_proc = subprocess.Popen(vlc_command, stdout=subprocess.PIPE) - vlc_version = vlc_proc.stdout.read() - vlc_proc.terminate() - vlc_proc.communicate() - vlc_version = vlc_version.decode().split("version ")[1].split('\n')[0] - except FileNotFoundError: - vlc_version = None - self.dict["vlc"]["version"] = vlc_version - else: - self.dict["vlc"]["version"] = "N/A" - if not self.dict["fhdhr"]["discovery_address"] and self.dict["fhdhr"]["address"] != "0.0.0.0": self.dict["fhdhr"]["discovery_address"] = self.dict["fhdhr"]["address"] if not self.dict["fhdhr"]["discovery_address"] or self.dict["fhdhr"]["discovery_address"] == "0.0.0.0": @@ -227,7 +275,7 @@ class Config(): # Create a custom logger logging.basicConfig(format='%(name)s - %(levelname)s - %(message)s', level=log_level) logger = logging.getLogger('fHDHR') - log_file = os.path.join(self.dict["filedir"]["logs_dir"], 'fHDHR.log') + log_file = os.path.join(self.internal["paths"]["logs_dir"], 'fHDHR.log') # Create handlers # c_handler = logging.StreamHandler() diff --git a/fHDHR/db/__init__.py b/fHDHR/db/__init__.py index 0533b46..86fd530 100644 --- a/fHDHR/db/__init__.py +++ b/fHDHR/db/__init__.py @@ -104,7 +104,7 @@ class fHDHRdb(object): db_user = self.config.dict["database"]["user"] db_pass = self.config.dict["database"]["pass"] db_host = self.config.dict["database"]["host"] - db_port = self.config.dict["database"]["prt"] # Optional + db_port = self.config.dict["database"]["port"] # Optional db_name = self.config.dict["database"]["name"] # Optional, depending on DB # Ensure we have all our variables defined diff --git a/fHDHR/device/epgtypes/zap2it.py b/fHDHR/device/epgtypes/zap2it.py index d7950f9..f2bb325 100644 --- a/fHDHR/device/epgtypes/zap2it.py +++ b/fHDHR/device/epgtypes/zap2it.py @@ -14,8 +14,6 @@ class zap2itEPG(): self.postalcode = self.fhdhr.config.dict["zap2it"]["postalcode"] - self.fhdhr.web_cache_dir = self.fhdhr.config.dict["filedir"]["epg_cache"]["zap2it"]["web_cache"] - def get_location(self): self.fhdhr.logger.warning("Zap2it postalcode not set, attempting to retrieve.") if not self.postalcode: diff --git a/fHDHR/device/images.py b/fHDHR/device/images.py index 171dbca..1a8befd 100644 --- a/fHDHR/device/images.py +++ b/fHDHR/device/images.py @@ -35,7 +35,7 @@ class imageHandler(): colorBackground = "#228822" colorText = "#717D7E" colorOutline = "#717D7E" - fontname = str(self.fhdhr.config.dict["filedir"]["font"]) + fontname = str(self.fhdhr.config.internal["paths"]["font"]) font = PIL.ImageFont.truetype(fontname, fontsize) text_width, text_height = self.getSize(message, font) diff --git a/fHDHR/device/tuners/stream/ffmpeg_stream.py b/fHDHR/device/tuners/stream/ffmpeg_stream.py index d018747..6550865 100644 --- a/fHDHR/device/tuners/stream/ffmpeg_stream.py +++ b/fHDHR/device/tuners/stream/ffmpeg_stream.py @@ -42,7 +42,7 @@ class FFMPEG_Stream(): def ffmpeg_command_assemble(self, stream_args): ffmpeg_command = [ - self.fhdhr.config.dict["ffmpeg"]["ffmpeg_path"], + self.fhdhr.config.dict["ffmpeg"]["path"], "-i", stream_args["channelUri"], ] ffmpeg_command.extend(self.ffmpeg_duration(stream_args)) diff --git a/fHDHR/device/tuners/stream/vlc_stream.py b/fHDHR/device/tuners/stream/vlc_stream.py index acce733..78b6a9b 100644 --- a/fHDHR/device/tuners/stream/vlc_stream.py +++ b/fHDHR/device/tuners/stream/vlc_stream.py @@ -44,7 +44,7 @@ class VLC_Stream(): def vlc_command_assemble(self, stream_args): vlc_command = [ - self.fhdhr.config.dict["vlc"]["vlc_path"], + self.fhdhr.config.dict["vlc"]["path"], "-I", "dummy", stream_args["channelUri"], ] vlc_command.extend(self.vlc_duration(stream_args)) diff --git a/fHDHR/http/__init__.py b/fHDHR/http/__init__.py index 9bf1f2f..30e755e 100644 --- a/fHDHR/http/__init__.py +++ b/fHDHR/http/__init__.py @@ -13,7 +13,7 @@ class fHDHR_HTTP_Server(): def __init__(self, fhdhr): self.fhdhr = fhdhr - self.template_folder = fhdhr.config.dict["filedir"]["www_templates_dir"] + self.template_folder = fhdhr.config.internal["paths"]["www_templates_dir"] self.app = Flask("fHDHR", template_folder=self.template_folder) diff --git a/fHDHR/http/api/__init__.py b/fHDHR/http/api/__init__.py index 8a04be2..0e8e65f 100644 --- a/fHDHR/http/api/__init__.py +++ b/fHDHR/http/api/__init__.py @@ -1,5 +1,6 @@ from .cluster import Cluster +from .settings import Settings from .channels import Channels from .lineup_post import Lineup_Post from .xmltv import xmlTV @@ -17,6 +18,7 @@ class fHDHR_API(): self.fhdhr = fhdhr self.cluster = Cluster(fhdhr) + self.settings = Settings(fhdhr) self.channels = Channels(fhdhr) self.xmltv = xmlTV(fhdhr) self.m3u = M3U(fhdhr) diff --git a/fHDHR/http/api/settings.py b/fHDHR/http/api/settings.py new file mode 100644 index 0000000..a4fcf19 --- /dev/null +++ b/fHDHR/http/api/settings.py @@ -0,0 +1,40 @@ +from flask import request, redirect +import urllib.parse + + +class Settings(): + endpoints = ["/api/settings"] + endpoint_name = "api_settings" + endpoint_methods = ["GET", "POST"] + + def __init__(self, fhdhr): + self.fhdhr = fhdhr + + def __call__(self, *args): + return self.get(*args) + + def get(self, *args): + + method = request.args.get('method', default="get", type=str) + redirect_url = request.args.get('redirect', default=None, type=str) + + if method == "update": + config_section = request.form.get('config_section', None) + config_name = request.form.get('config_name', None) + config_value = request.form.get('config_value', None) + + if not config_section or not config_name or not config_value: + if redirect_url: + return redirect(redirect_url + "?retmessage=" + urllib.parse.quote("%s Failed" % method)) + else: + return "%s Falied" % method + + if config_section == "origin": + config_section = self.fhdhr.config.dict["main"]["dictpopname"] + + self.fhdhr.config.write(config_section, config_name, config_value) + + if redirect_url: + return redirect(redirect_url + "?retmessage=" + urllib.parse.quote("%s Success" % method)) + else: + return "%s Success" % method diff --git a/fHDHR/http/files/favicon_ico.py b/fHDHR/http/files/favicon_ico.py index 2f1d5b8..890a0c5 100644 --- a/fHDHR/http/files/favicon_ico.py +++ b/fHDHR/http/files/favicon_ico.py @@ -13,6 +13,6 @@ class Favicon_ICO(): def get(self, *args): - return send_from_directory(self.fhdhr.config.dict["filedir"]["www_dir"], + return send_from_directory(self.fhdhr.config.internal["paths"]["www_dir"], 'favicon.ico', mimetype='image/vnd.microsoft.icon') diff --git a/fHDHR/http/files/style_css.py b/fHDHR/http/files/style_css.py index 28ccd3a..e6e3134 100644 --- a/fHDHR/http/files/style_css.py +++ b/fHDHR/http/files/style_css.py @@ -13,5 +13,5 @@ class Style_CSS(): def get(self, *args): - return send_from_directory(self.fhdhr.config.dict["filedir"]["www_dir"], + return send_from_directory(self.fhdhr.config.internal["paths"]["www_dir"], 'style.css') diff --git a/fHDHR/http/pages/__init__.py b/fHDHR/http/pages/__init__.py index 10d8f3a..ce705b1 100644 --- a/fHDHR/http/pages/__init__.py +++ b/fHDHR/http/pages/__init__.py @@ -8,6 +8,7 @@ from .streams_html import Streams_HTML from .version_html import Version_HTML from .guide_html import Guide_HTML from .xmltv_html import xmlTV_HTML +from .settings import Settings_HTML class fHDHR_Pages(): @@ -16,6 +17,7 @@ class fHDHR_Pages(): self.fhdhr = fhdhr self.index = Index_HTML(fhdhr) + self.settings = Settings_HTML(fhdhr) self.origin = Origin_HTML(fhdhr) self.cluster = Cluster_HTML(fhdhr) self.diagnostics = Diagnostics_HTML(fhdhr) diff --git a/fHDHR/http/pages/index_html.py b/fHDHR/http/pages/index_html.py index 97c7b55..c2aa00f 100644 --- a/fHDHR/http/pages/index_html.py +++ b/fHDHR/http/pages/index_html.py @@ -17,9 +17,9 @@ class Index_HTML(): max_tuners = self.fhdhr.device.tuners.max_tuners fhdhr_status_dict = { - "Script Directory": str(self.fhdhr.config.dict["filedir"]["script_dir"]), + "Script Directory": str(self.fhdhr.config.internal["paths"]["script_dir"]), "Config File": str(self.fhdhr.config.config_file), - "Cache Path": str(self.fhdhr.config.dict["filedir"]["cache_dir"]), + "Cache Path": str(self.fhdhr.config.internal["paths"]["cache_dir"]), "Total Channels": str(self.fhdhr.device.channels.get_station_total()), "Tuner Usage": ("%s/%s" % (str(tuners_in_use), str(max_tuners))), } diff --git a/fHDHR/http/pages/settings.py b/fHDHR/http/pages/settings.py new file mode 100644 index 0000000..80674b4 --- /dev/null +++ b/fHDHR/http/pages/settings.py @@ -0,0 +1,33 @@ +from flask import request, render_template + + +class Settings_HTML(): + endpoints = ["/settings", "/settings.html"] + endpoint_name = "settings" + + def __init__(self, fhdhr): + self.fhdhr = fhdhr + + def __call__(self, *args): + return self.get(*args) + + def get(self, *args): + + web_settings_dict = {} + for config_section in list(self.fhdhr.config.conf_default.keys()): + web_settings_dict[config_section] = {} + + for config_item in list(self.fhdhr.config.conf_default[config_section].keys()): + if self.fhdhr.config.conf_default[config_section][config_item]["config_web"]: + real_config_section = config_section + if config_section == self.fhdhr.config.dict["main"]["dictpopname"]: + real_config_section = "origin" + web_settings_dict[config_section][config_item] = { + "value": self.fhdhr.config.dict[real_config_section][config_item], + "value_default": self.fhdhr.config.conf_default[config_section][config_item]["value"], + "hide": self.fhdhr.config.conf_default[config_section][config_item]["config_web_hidden"] + } + if not len(web_settings_dict[config_section].keys()): + del web_settings_dict[config_section] + + return render_template('settings.html', request=request, fhdhr=self.fhdhr, web_settings_dict=web_settings_dict, list=list) diff --git a/fHDHR/http/pages/version_html.py b/fHDHR/http/pages/version_html.py index e5fce4e..66d952f 100644 --- a/fHDHR/http/pages/version_html.py +++ b/fHDHR/http/pages/version_html.py @@ -17,9 +17,9 @@ class Version_HTML(): version_dict = { "fHDHR": self.fhdhr.version, "Python": sys.version, - "Operating System": self.fhdhr.config.dict["main"]["opersystem"], - "Using Docker": self.fhdhr.config.dict["main"]["isdocker"], - "ffmpeg": self.fhdhr.config.dict["ffmpeg"]["version"], - "vlc": self.fhdhr.config.dict["vlc"]["version"], + "Operating System": self.fhdhr.config.internal["versions"]["opersystem"], + "Using Docker": self.fhdhr.config.internal["versions"]["isdocker"], + "ffmpeg": self.fhdhr.config.internal["versions"]["ffmpeg"], + "vlc": self.fhdhr.config.internal["versions"]["vlc"], } return render_template('version.html', request=request, fhdhr=self.fhdhr, version_dict=version_dict, list=list)