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 %}
+
+
+
+ | Config Name |
+ Config Default Value |
+ Config Value |
+ Update |
+ Reset |
+
+
+ {% for config_item in list(web_settings_dict[config_section].keys()) %}
+
+
+ | {{ config_item }} |
+
+ {{ web_settings_dict[config_section][config_item]["value_default"] }} |
+
+
+
+
+
+
+
+ {% endfor %}
+
+
+ {% 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)