mirror of
https://github.com/fHDHR/fHDHR_NextPVR.git
synced 2025-12-06 08:46:58 -05:00
Add Settings Page, and overhaul Config system
This commit is contained in:
parent
e98c53526d
commit
38e98d7000
@ -24,7 +24,7 @@
|
|||||||
# update_frequency = 43200
|
# update_frequency = 43200
|
||||||
|
|
||||||
[ffmpeg]
|
[ffmpeg]
|
||||||
# ffmpeg_path = ffmpeg
|
# path = ffmpeg
|
||||||
# bytes_per_read = 1152000
|
# bytes_per_read = 1152000
|
||||||
|
|
||||||
[direct_stream]
|
[direct_stream]
|
||||||
|
|||||||
@ -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
|
|
||||||
148
data/internal_config/fhdhr.json
Normal file
148
data/internal_config/fhdhr.json
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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 =
|
|
||||||
91
data/internal_config/serviceconf.json
Normal file
91
data/internal_config/serviceconf.json
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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 = -
|
|
||||||
64
data/internal_config/zap2it.json
Normal file
64
data/internal_config/zap2it.json
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -24,6 +24,7 @@
|
|||||||
<button class="pull-left" onclick="OpenLink('/xmltv')">xmltv</a></button>
|
<button class="pull-left" onclick="OpenLink('/xmltv')">xmltv</a></button>
|
||||||
<button class="pull-left" onclick="OpenLink('/version')">Version</a></button>
|
<button class="pull-left" onclick="OpenLink('/version')">Version</a></button>
|
||||||
<button class="pull-left" onclick="OpenLink('/diagnostics')">Diagnostics</a></button>
|
<button class="pull-left" onclick="OpenLink('/diagnostics')">Diagnostics</a></button>
|
||||||
|
<button class="pull-left" onclick="OpenLink('/settings')">Settings</a></button>
|
||||||
|
|
||||||
<a class="pull-right" style="padding: 5px;" href="/api/xmltv?method=get&source={{ fhdhr.device.epg.def_method }}">xmltv</a>
|
<a class="pull-right" style="padding: 5px;" href="/api/xmltv?method=get&source={{ fhdhr.device.epg.def_method }}">xmltv</a>
|
||||||
<a class="pull-right" style="padding: 5px;" href="/api/m3u?method=get&channel=all">m3u</a>
|
<a class="pull-right" style="padding: 5px;" href="/api/m3u?method=get&channel=all">m3u</a>
|
||||||
|
|||||||
60
data/www/templates/settings.html
Normal file
60
data/www/templates/settings.html
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<h4 style="text-align: center;">fHDHR Settings</h4>
|
||||||
|
|
||||||
|
<h4 style="text-align: center;">Settings will require a manual restart.</h4>
|
||||||
|
|
||||||
|
{% for config_section in list(web_settings_dict.keys()) %}
|
||||||
|
|
||||||
|
{% if config_section == "origin" %}
|
||||||
|
<h4 style="text-align: center;">{{ fhdhr.config.dict["main"]["dictpopname"] }}</h4>
|
||||||
|
{% else %}
|
||||||
|
<h4 style="text-align: center;">{{ config_section }}</h4>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<table class="center" style="width:100%">
|
||||||
|
<tr>
|
||||||
|
<th>Config Name</th>
|
||||||
|
<th>Config Default Value</th>
|
||||||
|
<th>Config Value</th>
|
||||||
|
<th>Update</th>
|
||||||
|
<th>Reset</th>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{% for config_item in list(web_settings_dict[config_section].keys()) %}
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td data-th="Config Name">{{ config_item }}</td>
|
||||||
|
|
||||||
|
<td data-th="Config Default Value">{{ web_settings_dict[config_section][config_item]["value_default"] }}</td>
|
||||||
|
|
||||||
|
<form method="post" action="/api/settings?method=update&redirect=%2Fsettings">
|
||||||
|
<input type="hidden" name="config_section" value={{ config_section }}>
|
||||||
|
<input type="hidden" name="config_name" value={{ config_item }}>
|
||||||
|
<input type="hidden" name="config_default" value={{ web_settings_dict[config_section][config_item]["value_default"] }}>
|
||||||
|
{% if web_settings_dict[config_section][config_item]["hide"] %}
|
||||||
|
<td data-th="Config Value"><input type="text" size="50" name="config_value" value=**************></td>
|
||||||
|
{% else %}
|
||||||
|
<td data-th="Config Value"><input type="text" size="50" name="config_value" value={{ web_settings_dict[config_section][config_item]["value"] }}></td>
|
||||||
|
{% endif %}
|
||||||
|
<td data-th="Update"><input type="submit" value="Update"></td>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<form method="post" action="/api/settings?method=update&redirect=%2Fsettings">
|
||||||
|
<input type="hidden" name="config_section" value={{ config_section }}>
|
||||||
|
<input type="hidden" name="config_name" value={{ config_item }}>
|
||||||
|
<input type="hidden" name="config_value" value={{ web_settings_dict[config_section][config_item]["value_default"] }}>
|
||||||
|
<input type="hidden" name="config_default" value={{ web_settings_dict[config_section][config_item]["value_default"] }}>
|
||||||
|
<td data-th="Reset"><input type="submit" value="Reset"></td>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
@ -5,6 +5,7 @@ import pathlib
|
|||||||
import logging
|
import logging
|
||||||
import subprocess
|
import subprocess
|
||||||
import platform
|
import platform
|
||||||
|
import json
|
||||||
|
|
||||||
import fHDHR.exceptions
|
import fHDHR.exceptions
|
||||||
from fHDHR.tools import isint, isfloat, is_arithmetic, is_docker
|
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():
|
class Config():
|
||||||
|
|
||||||
def __init__(self, filename, script_dir):
|
def __init__(self, filename, script_dir):
|
||||||
|
self.internal = {}
|
||||||
|
self.conf_default = {}
|
||||||
self.dict = {}
|
self.dict = {}
|
||||||
self.config_file = filename
|
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()
|
self.config_verification()
|
||||||
|
|
||||||
def load_defaults(self, script_dir):
|
def initial_load(self, script_dir):
|
||||||
|
|
||||||
data_dir = pathlib.Path(script_dir).joinpath('data')
|
data_dir = pathlib.Path(script_dir).joinpath('data')
|
||||||
www_dir = pathlib.Path(data_dir).joinpath('www')
|
www_dir = pathlib.Path(data_dir).joinpath('www')
|
||||||
|
|
||||||
self.dict["filedir"] = {
|
self.internal["paths"] = {
|
||||||
"script_dir": script_dir,
|
"script_dir": script_dir,
|
||||||
"data_dir": data_dir,
|
"data_dir": data_dir,
|
||||||
|
|
||||||
"cache_dir": pathlib.Path(data_dir).joinpath('cache'),
|
"cache_dir": pathlib.Path(data_dir).joinpath('cache'),
|
||||||
"internal_config": pathlib.Path(data_dir).joinpath('internal_config'),
|
"internal_config": pathlib.Path(data_dir).joinpath('internal_config'),
|
||||||
"www_dir": www_dir,
|
"www_dir": www_dir,
|
||||||
"www_images_dir": pathlib.Path(www_dir).joinpath('images'),
|
|
||||||
"www_templates_dir": pathlib.Path(www_dir).joinpath('templates'),
|
"www_templates_dir": pathlib.Path(www_dir).joinpath('templates'),
|
||||||
"font": pathlib.Path(data_dir).joinpath('garamond.ttf'),
|
"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"]):
|
for conffile in os.listdir(self.internal["paths"]["internal_config"]):
|
||||||
conffilepath = os.path.join(self.dict["filedir"]["internal_config"], conffile)
|
conffilepath = os.path.join(self.internal["paths"]["internal_config"], conffile)
|
||||||
if str(conffilepath).endswith(".ini"):
|
if str(conffilepath).endswith(".json"):
|
||||||
self.read_config(conffilepath)
|
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 = configparser.ConfigParser()
|
||||||
config_handler.read(conffilepath)
|
config_handler.read(conffilepath)
|
||||||
for each_section in config_handler.sections():
|
for each_section in config_handler.sections():
|
||||||
@ -57,7 +164,9 @@ class Config():
|
|||||||
for (each_key, each_val) in config_handler.items(each_section):
|
for (each_key, each_val) in config_handler.items(each_section):
|
||||||
if not each_val:
|
if not each_val:
|
||||||
each_val = None
|
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
|
each_val = False
|
||||||
elif each_val.lower() in ["true"]:
|
elif each_val.lower() in ["true"]:
|
||||||
each_val = True
|
each_val = True
|
||||||
@ -69,7 +178,15 @@ class Config():
|
|||||||
each_val = eval(each_val)
|
each_val = eval(each_val)
|
||||||
elif "," in each_val:
|
elif "," in each_val:
|
||||||
each_val = each_val.split(",")
|
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):
|
def write(self, section, key, value):
|
||||||
if section == self.dict["main"]["dictpopname"]:
|
if section == self.dict["main"]["dictpopname"]:
|
||||||
@ -126,95 +243,26 @@ class Config():
|
|||||||
raise fHDHR.exceptions.ConfigurationError("Invalid EPG Method. Exiting...")
|
raise fHDHR.exceptions.ConfigurationError("Invalid EPG Method. Exiting...")
|
||||||
self.dict["epg"]["def_method"] = self.dict["epg"]["method"][0]
|
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"]:
|
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.dict["main"]["uuid"] = ''.join(random.choice("hijklmnopqrstuvwxyz") for i in range(8))
|
||||||
self.write('main', 'uuid', self.dict["main"]["uuid"])
|
self.write('main', 'uuid', self.dict["main"]["uuid"])
|
||||||
|
|
||||||
if self.dict["main"]["cache_dir"]:
|
if self.dict["main"]["cache_dir"]:
|
||||||
if not pathlib.Path(self.dict["main"]["cache_dir"]).is_dir():
|
if not pathlib.Path(self.dict["main"]["cache_dir"]).is_dir():
|
||||||
raise fHDHR.exceptions.ConfigurationError("Invalid Cache Directory. Exiting...")
|
raise fHDHR.exceptions.ConfigurationError("Invalid Cache Directory. Exiting...")
|
||||||
self.dict["filedir"]["cache_dir"] = pathlib.Path(self.dict["main"]["cache_dir"])
|
self.internal["paths"]["cache_dir"] = pathlib.Path(self.dict["main"]["cache_dir"])
|
||||||
cache_dir = self.dict["filedir"]["cache_dir"]
|
cache_dir = self.internal["paths"]["cache_dir"]
|
||||||
|
|
||||||
logs_dir = pathlib.Path(cache_dir).joinpath('logs')
|
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():
|
if not logs_dir.is_dir():
|
||||||
logs_dir.mkdir()
|
logs_dir.mkdir()
|
||||||
|
|
||||||
self.dict["database"]["path"] = pathlib.Path(cache_dir).joinpath('fhdhr.db')
|
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"]:
|
if self.dict["fhdhr"]["stream_type"] not in ["direct", "ffmpeg", "vlc"]:
|
||||||
raise fHDHR.exceptions.ConfigurationError("Invalid stream type. Exiting...")
|
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":
|
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"]
|
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":
|
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
|
# Create a custom logger
|
||||||
logging.basicConfig(format='%(name)s - %(levelname)s - %(message)s', level=log_level)
|
logging.basicConfig(format='%(name)s - %(levelname)s - %(message)s', level=log_level)
|
||||||
logger = logging.getLogger('fHDHR')
|
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
|
# Create handlers
|
||||||
# c_handler = logging.StreamHandler()
|
# c_handler = logging.StreamHandler()
|
||||||
|
|||||||
@ -104,7 +104,7 @@ class fHDHRdb(object):
|
|||||||
db_user = self.config.dict["database"]["user"]
|
db_user = self.config.dict["database"]["user"]
|
||||||
db_pass = self.config.dict["database"]["pass"]
|
db_pass = self.config.dict["database"]["pass"]
|
||||||
db_host = self.config.dict["database"]["host"]
|
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
|
db_name = self.config.dict["database"]["name"] # Optional, depending on DB
|
||||||
|
|
||||||
# Ensure we have all our variables defined
|
# Ensure we have all our variables defined
|
||||||
|
|||||||
@ -14,8 +14,6 @@ class zap2itEPG():
|
|||||||
|
|
||||||
self.postalcode = self.fhdhr.config.dict["zap2it"]["postalcode"]
|
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):
|
def get_location(self):
|
||||||
self.fhdhr.logger.warning("Zap2it postalcode not set, attempting to retrieve.")
|
self.fhdhr.logger.warning("Zap2it postalcode not set, attempting to retrieve.")
|
||||||
if not self.postalcode:
|
if not self.postalcode:
|
||||||
|
|||||||
@ -35,7 +35,7 @@ class imageHandler():
|
|||||||
colorBackground = "#228822"
|
colorBackground = "#228822"
|
||||||
colorText = "#717D7E"
|
colorText = "#717D7E"
|
||||||
colorOutline = "#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)
|
font = PIL.ImageFont.truetype(fontname, fontsize)
|
||||||
text_width, text_height = self.getSize(message, font)
|
text_width, text_height = self.getSize(message, font)
|
||||||
|
|||||||
@ -42,7 +42,7 @@ class FFMPEG_Stream():
|
|||||||
|
|
||||||
def ffmpeg_command_assemble(self, stream_args):
|
def ffmpeg_command_assemble(self, stream_args):
|
||||||
ffmpeg_command = [
|
ffmpeg_command = [
|
||||||
self.fhdhr.config.dict["ffmpeg"]["ffmpeg_path"],
|
self.fhdhr.config.dict["ffmpeg"]["path"],
|
||||||
"-i", stream_args["channelUri"],
|
"-i", stream_args["channelUri"],
|
||||||
]
|
]
|
||||||
ffmpeg_command.extend(self.ffmpeg_duration(stream_args))
|
ffmpeg_command.extend(self.ffmpeg_duration(stream_args))
|
||||||
|
|||||||
@ -44,7 +44,7 @@ class VLC_Stream():
|
|||||||
|
|
||||||
def vlc_command_assemble(self, stream_args):
|
def vlc_command_assemble(self, stream_args):
|
||||||
vlc_command = [
|
vlc_command = [
|
||||||
self.fhdhr.config.dict["vlc"]["vlc_path"],
|
self.fhdhr.config.dict["vlc"]["path"],
|
||||||
"-I", "dummy", stream_args["channelUri"],
|
"-I", "dummy", stream_args["channelUri"],
|
||||||
]
|
]
|
||||||
vlc_command.extend(self.vlc_duration(stream_args))
|
vlc_command.extend(self.vlc_duration(stream_args))
|
||||||
|
|||||||
@ -13,7 +13,7 @@ class fHDHR_HTTP_Server():
|
|||||||
def __init__(self, fhdhr):
|
def __init__(self, fhdhr):
|
||||||
self.fhdhr = 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)
|
self.app = Flask("fHDHR", template_folder=self.template_folder)
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
from .cluster import Cluster
|
from .cluster import Cluster
|
||||||
|
from .settings import Settings
|
||||||
from .channels import Channels
|
from .channels import Channels
|
||||||
from .lineup_post import Lineup_Post
|
from .lineup_post import Lineup_Post
|
||||||
from .xmltv import xmlTV
|
from .xmltv import xmlTV
|
||||||
@ -17,6 +18,7 @@ class fHDHR_API():
|
|||||||
self.fhdhr = fhdhr
|
self.fhdhr = fhdhr
|
||||||
|
|
||||||
self.cluster = Cluster(fhdhr)
|
self.cluster = Cluster(fhdhr)
|
||||||
|
self.settings = Settings(fhdhr)
|
||||||
self.channels = Channels(fhdhr)
|
self.channels = Channels(fhdhr)
|
||||||
self.xmltv = xmlTV(fhdhr)
|
self.xmltv = xmlTV(fhdhr)
|
||||||
self.m3u = M3U(fhdhr)
|
self.m3u = M3U(fhdhr)
|
||||||
|
|||||||
40
fHDHR/http/api/settings.py
Normal file
40
fHDHR/http/api/settings.py
Normal file
@ -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
|
||||||
@ -13,6 +13,6 @@ class Favicon_ICO():
|
|||||||
|
|
||||||
def get(self, *args):
|
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',
|
'favicon.ico',
|
||||||
mimetype='image/vnd.microsoft.icon')
|
mimetype='image/vnd.microsoft.icon')
|
||||||
|
|||||||
@ -13,5 +13,5 @@ class Style_CSS():
|
|||||||
|
|
||||||
def get(self, *args):
|
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')
|
'style.css')
|
||||||
|
|||||||
@ -8,6 +8,7 @@ from .streams_html import Streams_HTML
|
|||||||
from .version_html import Version_HTML
|
from .version_html import Version_HTML
|
||||||
from .guide_html import Guide_HTML
|
from .guide_html import Guide_HTML
|
||||||
from .xmltv_html import xmlTV_HTML
|
from .xmltv_html import xmlTV_HTML
|
||||||
|
from .settings import Settings_HTML
|
||||||
|
|
||||||
|
|
||||||
class fHDHR_Pages():
|
class fHDHR_Pages():
|
||||||
@ -16,6 +17,7 @@ class fHDHR_Pages():
|
|||||||
self.fhdhr = fhdhr
|
self.fhdhr = fhdhr
|
||||||
|
|
||||||
self.index = Index_HTML(fhdhr)
|
self.index = Index_HTML(fhdhr)
|
||||||
|
self.settings = Settings_HTML(fhdhr)
|
||||||
self.origin = Origin_HTML(fhdhr)
|
self.origin = Origin_HTML(fhdhr)
|
||||||
self.cluster = Cluster_HTML(fhdhr)
|
self.cluster = Cluster_HTML(fhdhr)
|
||||||
self.diagnostics = Diagnostics_HTML(fhdhr)
|
self.diagnostics = Diagnostics_HTML(fhdhr)
|
||||||
|
|||||||
@ -17,9 +17,9 @@ class Index_HTML():
|
|||||||
max_tuners = self.fhdhr.device.tuners.max_tuners
|
max_tuners = self.fhdhr.device.tuners.max_tuners
|
||||||
|
|
||||||
fhdhr_status_dict = {
|
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),
|
"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()),
|
"Total Channels": str(self.fhdhr.device.channels.get_station_total()),
|
||||||
"Tuner Usage": ("%s/%s" % (str(tuners_in_use), str(max_tuners))),
|
"Tuner Usage": ("%s/%s" % (str(tuners_in_use), str(max_tuners))),
|
||||||
}
|
}
|
||||||
|
|||||||
33
fHDHR/http/pages/settings.py
Normal file
33
fHDHR/http/pages/settings.py
Normal file
@ -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)
|
||||||
@ -17,9 +17,9 @@ class Version_HTML():
|
|||||||
version_dict = {
|
version_dict = {
|
||||||
"fHDHR": self.fhdhr.version,
|
"fHDHR": self.fhdhr.version,
|
||||||
"Python": sys.version,
|
"Python": sys.version,
|
||||||
"Operating System": self.fhdhr.config.dict["main"]["opersystem"],
|
"Operating System": self.fhdhr.config.internal["versions"]["opersystem"],
|
||||||
"Using Docker": self.fhdhr.config.dict["main"]["isdocker"],
|
"Using Docker": self.fhdhr.config.internal["versions"]["isdocker"],
|
||||||
"ffmpeg": self.fhdhr.config.dict["ffmpeg"]["version"],
|
"ffmpeg": self.fhdhr.config.internal["versions"]["ffmpeg"],
|
||||||
"vlc": self.fhdhr.config.dict["vlc"]["version"],
|
"vlc": self.fhdhr.config.internal["versions"]["vlc"],
|
||||||
}
|
}
|
||||||
return render_template('version.html', request=request, fhdhr=self.fhdhr, version_dict=version_dict, list=list)
|
return render_template('version.html', request=request, fhdhr=self.fhdhr, version_dict=version_dict, list=list)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user