mirror of
https://github.com/fHDHR/fHDHR_NextPVR.git
synced 2025-12-06 06:56:57 -05:00
Compare commits
6 Commits
22955ce11f
...
13faf0845e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
13faf0845e | ||
|
|
1cf2a7acce | ||
|
|
36712e7ba0 | ||
|
|
02e825978b | ||
|
|
9642feecae | ||
|
|
b8ce4f4e8a |
@ -24,11 +24,6 @@
|
||||
"value": "fHDHR",
|
||||
"config_file": false,
|
||||
"config_web": false
|
||||
},
|
||||
"required":{
|
||||
"value": "none",
|
||||
"config_file": false,
|
||||
"config_web": false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,19 +20,5 @@
|
||||
"config_file": true,
|
||||
"config_web": true
|
||||
}
|
||||
},
|
||||
"ffmpeg":{
|
||||
"path":{
|
||||
"value": "ffmpeg",
|
||||
"config_file": true,
|
||||
"config_web": true
|
||||
}
|
||||
},
|
||||
"vlc":{
|
||||
"path":{
|
||||
"value": "cvlc",
|
||||
"config_file": true,
|
||||
"config_web": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,7 +3,6 @@ import sys
|
||||
import random
|
||||
import configparser
|
||||
import pathlib
|
||||
import subprocess
|
||||
import platform
|
||||
import json
|
||||
|
||||
@ -23,21 +22,20 @@ class Config():
|
||||
self.dict = {}
|
||||
self.config_file = filename
|
||||
|
||||
self.initial_load(script_dir)
|
||||
self.core_setup(script_dir)
|
||||
self.plugins_setup()
|
||||
self.user_config()
|
||||
self.config_verification()
|
||||
|
||||
def initial_load(self, script_dir):
|
||||
def core_setup(self, script_dir):
|
||||
|
||||
data_dir = pathlib.Path(script_dir).joinpath('data')
|
||||
fHDHR_web_dir = pathlib.Path(script_dir).joinpath('fHDHR_web')
|
||||
www_dir = pathlib.Path(fHDHR_web_dir).joinpath('www_dir')
|
||||
origin_dir = [self.plugins.plugin_dict[x]["PATH"] for x in list(self.plugins.plugin_dict.keys()) if self.plugins.plugin_dict[x]["TYPE"] == "origin"][0]
|
||||
|
||||
self.internal["paths"] = {
|
||||
"script_dir": script_dir,
|
||||
"data_dir": data_dir,
|
||||
"origin": origin_dir,
|
||||
"origin_web": pathlib.Path(origin_dir).joinpath('origin_web'),
|
||||
"cache_dir": pathlib.Path(data_dir).joinpath('cache'),
|
||||
"internal_config": pathlib.Path(data_dir).joinpath('internal_config'),
|
||||
"fHDHR_web_dir": fHDHR_web_dir,
|
||||
@ -56,15 +54,26 @@ class Config():
|
||||
if str(file_item_path).endswith("_conf.json"):
|
||||
self.read_json_config(file_item_path)
|
||||
|
||||
for dir_type in ["alt_epg", "origin"]:
|
||||
self.dict["epg"]["valid_methods"] = ["origin", "blocks", None]
|
||||
|
||||
self.dict["streaming"]["valid_methods"] = ["direct"]
|
||||
|
||||
self.load_versions()
|
||||
|
||||
def plugins_setup(self):
|
||||
|
||||
# Load Origin Paths
|
||||
origin_dir = [self.plugins.plugin_dict[x]["PATH"] for x in list(self.plugins.plugin_dict.keys()) if self.plugins.plugin_dict[x]["TYPE"] == "origin"][0]
|
||||
self.internal["paths"]["origin"] = origin_dir
|
||||
self.internal["paths"]["origin_web"] = pathlib.Path(origin_dir).joinpath('origin_web')
|
||||
|
||||
# Load Plugin Conf
|
||||
for dir_type in ["alt_epg", "origin", "alt_stream"]:
|
||||
if dir_type == "origin":
|
||||
dir_tops = [self.internal["paths"]["origin"]]
|
||||
elif dir_type == "alt_epg":
|
||||
dir_tops = [self.plugins.plugin_dict[x]["PATH"] for x in list(self.plugins.plugin_dict.keys()) if self.plugins.plugin_dict[x]["TYPE"] == "alt_epg"]
|
||||
|
||||
elif dir_type in ["alt_stream", "alt_epg"]:
|
||||
dir_tops = [self.plugins.plugin_dict[x]["PATH"] for x in list(self.plugins.plugin_dict.keys()) if self.plugins.plugin_dict[x]["TYPE"] == dir_type]
|
||||
for top_dir in dir_tops:
|
||||
|
||||
for file_item in os.listdir(top_dir):
|
||||
file_item_path = pathlib.Path(top_dir).joinpath(file_item)
|
||||
if file_item_path.is_dir():
|
||||
@ -76,22 +85,33 @@ class Config():
|
||||
if str(file_item_path).endswith("_conf.json"):
|
||||
self.read_json_config(file_item_path)
|
||||
|
||||
print("Loading Configuration File: %s" % self.config_file)
|
||||
self.read_ini_config(self.config_file)
|
||||
# Rename the Origin conf section
|
||||
self.dict["origin"] = self.dict.pop(self.dict["main"]["dictpopname"])
|
||||
|
||||
self.load_versions()
|
||||
# Get Pltuin Version
|
||||
for plugin_item in list(self.plugins.plugin_dict.keys()):
|
||||
self.internal["versions"][plugin_item] = self.plugins.plugin_dict[plugin_item]["VERSION"]
|
||||
|
||||
# Run Plugin Setup Checks
|
||||
for plugin_item in list(self.plugins.plugin_dict.keys()):
|
||||
try:
|
||||
eval("self.plugins.%s_Setup(self)" % self.plugins.plugin_dict[plugin_item]["NAME"].upper())
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
self.dict["epg"]["valid_methods"].extend([self.plugins.plugin_dict[x]["NAME"] for x in list(self.plugins.plugin_dict.keys()) if self.plugins.plugin_dict[x]["TYPE"] == "alt_epg"])
|
||||
self.dict["streaming"]["valid_methods"].extend([self.plugins.plugin_dict[x]["NAME"] for x in list(self.plugins.plugin_dict.keys()) if self.plugins.plugin_dict[x]["TYPE"] == "alt_stream"])
|
||||
|
||||
def register_version(self, item_name, item_version):
|
||||
self.internal["versions"][item_name] = item_version
|
||||
|
||||
def load_versions(self):
|
||||
|
||||
self.internal["versions"] = {}
|
||||
|
||||
self.internal["versions"]["fHDHR"] = fHDHR_VERSION
|
||||
|
||||
self.internal["versions"]["fHDHR_web"] = self.fHDHR_web.fHDHR_web_VERSION
|
||||
|
||||
for plugin_item in list(self.plugins.plugin_dict.keys()):
|
||||
self.internal["versions"][plugin_item] = self.plugins.plugin_dict[plugin_item]["VERSION"]
|
||||
|
||||
self.internal["versions"]["Python"] = sys.version
|
||||
|
||||
opersystem = platform.system()
|
||||
@ -110,180 +130,26 @@ class Config():
|
||||
isdocker = is_docker()
|
||||
self.internal["versions"]["Docker"] = isdocker
|
||||
|
||||
if self.dict["streaming"]["method"] == "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_proc.kill()
|
||||
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["streaming"]["method"] == "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_proc.kill()
|
||||
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 key == "xmltv_offset":
|
||||
confvalue = str(confvalue)
|
||||
elif 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():
|
||||
if each_section.lower() not in list(self.dict.keys()):
|
||||
self.dict[each_section.lower()] = {}
|
||||
for (each_key, each_val) in config_handler.items(each_section):
|
||||
if not each_val:
|
||||
each_val = None
|
||||
elif each_key == "xmltv_offset":
|
||||
each_val = str(each_val)
|
||||
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
|
||||
elif isint(each_val):
|
||||
each_val = int(each_val)
|
||||
elif isfloat(each_val):
|
||||
each_val = float(each_val)
|
||||
elif is_arithmetic(each_val):
|
||||
each_val = eval(each_val)
|
||||
elif "," in each_val:
|
||||
each_val = each_val.split(",")
|
||||
|
||||
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 not value:
|
||||
value = None
|
||||
if value.lower() in ["none"]:
|
||||
value = None
|
||||
elif value.lower() in ["false"]:
|
||||
value = False
|
||||
elif value.lower() in ["true"]:
|
||||
value = True
|
||||
elif isint(value):
|
||||
value = int(value)
|
||||
elif isfloat(value):
|
||||
value = float(value)
|
||||
elif isinstance(value, list):
|
||||
",".join(value)
|
||||
|
||||
if section == self.dict["main"]["dictpopname"]:
|
||||
self.dict["origin"][key] = value
|
||||
else:
|
||||
self.dict[section][key] = value
|
||||
|
||||
config_handler = configparser.ConfigParser()
|
||||
config_handler.read(self.config_file)
|
||||
|
||||
if not config_handler.has_section(section):
|
||||
config_handler.add_section(section)
|
||||
|
||||
config_handler.set(section, key, str(value))
|
||||
|
||||
with open(self.config_file, 'w') as config_file:
|
||||
config_handler.write(config_file)
|
||||
def user_config(self):
|
||||
print("Loading Configuration File: %s" % self.config_file)
|
||||
self.read_ini_config(self.config_file)
|
||||
|
||||
def config_verification(self):
|
||||
|
||||
if self.dict["main"]["required"]:
|
||||
required_missing = []
|
||||
if isinstance(self.dict["main"]["required"], str):
|
||||
self.dict["main"]["required"] = [self.dict["main"]["required"]]
|
||||
if len(self.dict["main"]["required"]):
|
||||
for req_item in self.dict["main"]["required"]:
|
||||
req_section = req_item.split("/")[0]
|
||||
req_key = req_item.split("/")[1]
|
||||
if not self.dict[req_section][req_key]:
|
||||
required_missing.append(req_item)
|
||||
if len(required_missing):
|
||||
raise fHDHR.exceptions.ConfigurationError("Required configuration options missing: %s" % ", ".join(required_missing))
|
||||
|
||||
self.dict["origin"] = self.dict.pop(self.dict["main"]["dictpopname"])
|
||||
|
||||
self.dict["epg"]["valid_epg_methods"] = [self.plugins.plugin_dict[x]["NAME"] for x in list(self.plugins.plugin_dict.keys()) if self.plugins.plugin_dict[x]["TYPE"] == "alt_epg"]
|
||||
self.dict["epg"]["valid_epg_methods"].extend(["origin", "blocks", None])
|
||||
required_missing = {}
|
||||
# create dict and combine items
|
||||
for config_section in list(self.conf_default.keys()):
|
||||
for config_item in list(self.conf_default[config_section].keys()):
|
||||
if self.conf_default[config_section][config_item]["required"]:
|
||||
config_section_name = config_section
|
||||
if config_section == self.dict["main"]["dictpopname"]:
|
||||
config_section_name = "origin"
|
||||
if not self.dict[config_section_name][config_item]:
|
||||
if config_section not in list(required_missing.keys()):
|
||||
required_missing[config_section] = []
|
||||
required_missing[config_section].append(config_item)
|
||||
for config_section in list(required_missing.keys()):
|
||||
print("Warning! Required configuration options missing: [%s]%s" % (config_section, ", ".join(required_missing[config_section])))
|
||||
|
||||
if self.dict["epg"]["method"] and self.dict["epg"]["method"] not in ["None"]:
|
||||
if isinstance(self.dict["epg"]["method"], str):
|
||||
@ -294,7 +160,7 @@ class Config():
|
||||
epg_methods.append("origin")
|
||||
elif epg_method in ["None"]:
|
||||
raise fHDHR.exceptions.ConfigurationError("Invalid EPG Method. Exiting...")
|
||||
elif epg_method in self.dict["epg"]["valid_epg_methods"]:
|
||||
elif epg_method in self.dict["epg"]["valid_methods"]:
|
||||
epg_methods.append(epg_method)
|
||||
else:
|
||||
raise fHDHR.exceptions.ConfigurationError("Invalid EPG Method. Exiting...")
|
||||
@ -317,7 +183,7 @@ class Config():
|
||||
|
||||
self.dict["database"]["path"] = pathlib.Path(cache_dir).joinpath('fhdhr.db')
|
||||
|
||||
if self.dict["streaming"]["method"] not in ["direct", "ffmpeg", "vlc"]:
|
||||
if self.dict["streaming"]["method"] not in self.dict["streaming"]["valid_methods"]:
|
||||
raise fHDHR.exceptions.ConfigurationError("Invalid stream type. Exiting...")
|
||||
|
||||
if not self.dict["fhdhr"]["discovery_address"] and self.dict["fhdhr"]["address"] != "0.0.0.0":
|
||||
@ -325,6 +191,114 @@ class Config():
|
||||
if not self.dict["fhdhr"]["discovery_address"] or self.dict["fhdhr"]["discovery_address"] == "0.0.0.0":
|
||||
self.dict["fhdhr"]["discovery_address"] = None
|
||||
|
||||
def get_real_conf_value(self, key, confvalue):
|
||||
if not confvalue:
|
||||
confvalue = None
|
||||
elif key == "xmltv_offset":
|
||||
confvalue = str(confvalue)
|
||||
elif 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
|
||||
return confvalue
|
||||
|
||||
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 = self.get_real_conf_value(key, confimport[section][key]["value"])
|
||||
|
||||
self.dict[section][key] = confvalue
|
||||
|
||||
self.conf_default[section][key]["value"] = confvalue
|
||||
|
||||
for config_option in ["config_web_hidden", "config_file", "config_web", "required"]:
|
||||
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():
|
||||
if each_section.lower() not in list(self.dict.keys()):
|
||||
self.dict[each_section.lower()] = {}
|
||||
for (each_key, each_val) in config_handler.items(each_section):
|
||||
each_val = self.get_real_conf_value(each_key, 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:
|
||||
if each_section == self.dict["main"]["dictpopname"]:
|
||||
each_section = "origin"
|
||||
self.dict[each_section.lower()][each_key.lower()] = each_val
|
||||
|
||||
def write(self, section, key, value):
|
||||
|
||||
if not value:
|
||||
value = None
|
||||
if value.lower() in ["none"]:
|
||||
value = None
|
||||
elif value.lower() in ["false"]:
|
||||
value = False
|
||||
elif value.lower() in ["true"]:
|
||||
value = True
|
||||
elif isint(value):
|
||||
value = int(value)
|
||||
elif isfloat(value):
|
||||
value = float(value)
|
||||
elif isinstance(value, list):
|
||||
",".join(value)
|
||||
|
||||
if section == self.dict["main"]["dictpopname"]:
|
||||
section = "origin"
|
||||
self.dict[section][key] = value
|
||||
|
||||
config_handler = configparser.ConfigParser()
|
||||
config_handler.read(self.config_file)
|
||||
|
||||
if not config_handler.has_section(section):
|
||||
config_handler.add_section(section)
|
||||
|
||||
config_handler.set(section, key, str(value))
|
||||
|
||||
with open(self.config_file, 'w') as config_file:
|
||||
config_handler.write(config_file)
|
||||
|
||||
def __getattr__(self, name):
|
||||
''' will only get called for undefined attributes '''
|
||||
if name in list(self.dict.keys()):
|
||||
|
||||
@ -14,7 +14,7 @@ class fHDHR_Device():
|
||||
|
||||
self.epg = EPG(fhdhr, self.channels, originwrapper, plugins)
|
||||
|
||||
self.tuners = Tuners(fhdhr, self.epg, self.channels)
|
||||
self.tuners = Tuners(fhdhr, self.epg, self.channels, plugins)
|
||||
|
||||
self.images = imageHandler(fhdhr, self.epg)
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ class EPG():
|
||||
self.epgdict = {}
|
||||
|
||||
self.epg_methods = self.fhdhr.config.dict["epg"]["method"]
|
||||
self.valid_epg_methods = [x for x in self.fhdhr.config.dict["epg"]["valid_epg_methods"] if x and x not in [None, "None"]]
|
||||
self.valid_epg_methods = [x for x in self.fhdhr.config.dict["epg"]["valid_methods"] if x and x not in [None, "None"]]
|
||||
|
||||
self.blocks = blocksEPG(self.fhdhr, self.channels)
|
||||
self.epg_handling = {
|
||||
@ -46,7 +46,7 @@ class EPG():
|
||||
if not method:
|
||||
method = self.def_method
|
||||
if (method == self.fhdhr.config.dict["main"]["dictpopname"] or
|
||||
method not in self.fhdhr.config.dict["epg"]["valid_epg_methods"]):
|
||||
method not in self.fhdhr.config.dict["epg"]["valid_methods"]):
|
||||
method = "origin"
|
||||
|
||||
epgtypename = method
|
||||
@ -92,7 +92,7 @@ class EPG():
|
||||
if not method:
|
||||
method = self.def_method
|
||||
if (method == self.fhdhr.config.dict["main"]["dictpopname"] or
|
||||
method not in self.fhdhr.config.dict["epg"]["valid_epg_methods"]):
|
||||
method not in self.fhdhr.config.dict["epg"]["valid_methods"]):
|
||||
method = "origin"
|
||||
|
||||
channel_guide_dict = {}
|
||||
@ -121,7 +121,7 @@ class EPG():
|
||||
if not method:
|
||||
method = self.def_method
|
||||
if (method == self.fhdhr.config.dict["main"]["dictpopname"] or
|
||||
method not in self.fhdhr.config.dict["epg"]["valid_epg_methods"]):
|
||||
method not in self.fhdhr.config.dict["epg"]["valid_methods"]):
|
||||
method = "origin"
|
||||
|
||||
if method in list(self.epgdict.keys()):
|
||||
@ -160,7 +160,7 @@ class EPG():
|
||||
def update(self, method=None):
|
||||
|
||||
if (not method or
|
||||
method not in self.fhdhr.config.dict["epg"]["valid_epg_methods"]):
|
||||
method not in self.fhdhr.config.dict["epg"]["valid_methods"]):
|
||||
method = self.def_method
|
||||
|
||||
if method == self.fhdhr.config.dict["main"]["dictpopname"]:
|
||||
|
||||
@ -7,9 +7,10 @@ from .tuner import Tuner
|
||||
|
||||
class Tuners():
|
||||
|
||||
def __init__(self, fhdhr, epg, channels):
|
||||
def __init__(self, fhdhr, epg, channels, plugins):
|
||||
self.fhdhr = fhdhr
|
||||
self.channels = channels
|
||||
self.plugins = plugins
|
||||
|
||||
self.epg = epg
|
||||
self.max_tuners = int(self.fhdhr.config.dict["fhdhr"]["tuner_count"])
|
||||
@ -19,7 +20,7 @@ class Tuners():
|
||||
self.fhdhr.logger.info("Creating %s tuners." % str(self.max_tuners))
|
||||
|
||||
for i in range(0, self.max_tuners):
|
||||
self.tuners[str(i)] = Tuner(fhdhr, i, epg)
|
||||
self.tuners[str(i)] = Tuner(fhdhr, i, epg, plugins)
|
||||
|
||||
def get_available_tuner(self):
|
||||
return next(tunernum for tunernum in list(self.tuners.keys()) if not self.tuners[tunernum].tuner_lock.locked()) or None
|
||||
|
||||
@ -2,26 +2,24 @@
|
||||
|
||||
from .direct_stream import Direct_Stream
|
||||
from .direct_m3u8_stream import Direct_M3U8_Stream
|
||||
from .ffmpeg_stream import FFMPEG_Stream
|
||||
from .vlc_stream import VLC_Stream
|
||||
|
||||
|
||||
class Stream():
|
||||
|
||||
def __init__(self, fhdhr, stream_args, tuner):
|
||||
def __init__(self, fhdhr, stream_args, tuner, plugins):
|
||||
self.fhdhr = fhdhr
|
||||
self.stream_args = stream_args
|
||||
|
||||
if stream_args["method"] == "ffmpeg":
|
||||
self.method = FFMPEG_Stream(fhdhr, stream_args, tuner)
|
||||
if stream_args["method"] == "vlc":
|
||||
self.method = VLC_Stream(fhdhr, stream_args, tuner)
|
||||
elif (stream_args["method"] == "direct" and
|
||||
not self.stream_args["true_content_type"].startswith(tuple(["application/", "text/"]))):
|
||||
self.method = Direct_Stream(fhdhr, stream_args, tuner)
|
||||
elif (stream_args["method"] == "direct" and
|
||||
self.stream_args["true_content_type"].startswith(tuple(["application/", "text/"]))):
|
||||
self.plugins = plugins
|
||||
|
||||
if stream_args["method"] == "direct":
|
||||
if self.stream_args["true_content_type"].startswith(tuple(["application/", "text/"])):
|
||||
self.method = Direct_M3U8_Stream(fhdhr, stream_args, tuner)
|
||||
else:
|
||||
self.method = Direct_Stream(fhdhr, stream_args, tuner)
|
||||
else:
|
||||
|
||||
self.method = eval("self.plugins.%s_Stream(fhdhr, stream_args, tuner)" % stream_args["method"].upper())
|
||||
|
||||
def get(self):
|
||||
return self.method.get()
|
||||
|
||||
@ -8,8 +8,9 @@ from .stream import Stream
|
||||
|
||||
|
||||
class Tuner():
|
||||
def __init__(self, fhdhr, inum, epg):
|
||||
def __init__(self, fhdhr, inum, epg, plugins):
|
||||
self.fhdhr = fhdhr
|
||||
self.plugins = plugins
|
||||
|
||||
self.number = inum
|
||||
self.epg = epg
|
||||
@ -76,7 +77,7 @@ class Tuner():
|
||||
self.status = {"status": "Inactive"}
|
||||
|
||||
def get_stream(self, stream_args, tuner):
|
||||
stream = Stream(self.fhdhr, stream_args, tuner)
|
||||
stream = Stream(self.fhdhr, stream_args, tuner, self.plugins)
|
||||
return stream.get()
|
||||
|
||||
def set_status(self, stream_args):
|
||||
|
||||
@ -23,7 +23,7 @@ class EPG():
|
||||
method = request.args.get('method', default="get", type=str)
|
||||
|
||||
source = request.args.get('source', default=self.fhdhr.config.dict["epg"]["def_method"], type=str)
|
||||
if source not in self.fhdhr.config.dict["epg"]["valid_epg_methods"]:
|
||||
if source not in self.fhdhr.config.dict["epg"]["valid_methods"]:
|
||||
return "%s Invalid xmltv method" % source
|
||||
|
||||
redirect_url = request.args.get('redirect', default=None, type=str)
|
||||
|
||||
@ -31,7 +31,7 @@ class Images():
|
||||
|
||||
elif method == "get":
|
||||
source = request.args.get('source', default=self.fhdhr.config.dict["epg"]["method"], type=str)
|
||||
if source in self.fhdhr.config.dict["epg"]["valid_epg_methods"]:
|
||||
if source in self.fhdhr.config.dict["epg"]["valid_methods"]:
|
||||
image_type = request.args.get('type', default="content", type=str)
|
||||
if image_type in ["content", "channel"]:
|
||||
image_id = request.args.get('id', default=None, type=str)
|
||||
|
||||
@ -31,7 +31,7 @@ class Tuners():
|
||||
|
||||
redirect_url = request.args.get('redirect', default=None, type=str)
|
||||
|
||||
if method in ["direct", "ffmpeg", "vlc"]:
|
||||
if method in self.fhdhr.config.dict["streaming"]["valid_methods"]:
|
||||
|
||||
channel_number = request.args.get('channel', None, type=str)
|
||||
if not channel_number:
|
||||
|
||||
@ -38,7 +38,7 @@ class xmlTV():
|
||||
method = request.args.get('method', default="get", type=str)
|
||||
|
||||
source = request.args.get('source', default=self.fhdhr.config.dict["epg"]["def_method"], type=str)
|
||||
if source not in self.fhdhr.config.dict["epg"]["valid_epg_methods"]:
|
||||
if source not in self.fhdhr.config.dict["epg"]["valid_methods"]:
|
||||
return "%s Invalid xmltv method" % source
|
||||
|
||||
redirect_url = request.args.get('redirect', default=None, type=str)
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
|
||||
{% for epg_method in fhdhr.config.dict["epg"]["valid_epg_methods"] %}
|
||||
{% for epg_method in fhdhr.config.dict["epg"]["valid_methods"] %}
|
||||
{% if epg_method not in [None, "None"] %}
|
||||
{% set epg_method_name = epg_method %}
|
||||
{% if epg_method == "origin" %}
|
||||
|
||||
@ -136,13 +136,13 @@ td {border: 1px solid black;}
|
||||
|
||||
/* Other options */
|
||||
|
||||
.table-scroll.text-edit-cols td:nth-child(-n+4),
|
||||
.table-scroll.text-edit-cols th:nth-child(-n+4){
|
||||
.table-scroll.text-edit-cols td:nth-of-type(-n+4),
|
||||
.table-scroll.text-edit-cols th:nth-of-type(-n+4){
|
||||
flex: 2
|
||||
}
|
||||
|
||||
.table-settings.text-edit-cols td:nth-child(-n+2),
|
||||
.table-settings.text-edit-cols th:nth-child(-n+2){
|
||||
.table-settings.text-edit-cols td:nth-of-type(-n+2),
|
||||
.table-settings.text-edit-cols th:nth-of-type(-n+2){
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
|
||||
@ -24,7 +24,7 @@ for entry in os.scandir(plugins_top_dir):
|
||||
|
||||
if curr_dict["TYPE"] == "origin":
|
||||
curr_dict["PATH"] = pathlib.Path(os.path.dirname(os.path.abspath(__file__))).joinpath(entry.name).joinpath('origin')
|
||||
elif curr_dict["TYPE"] == "alt_epg":
|
||||
elif curr_dict["TYPE"] in ["alt_epg", "alt_stream"]:
|
||||
curr_dict["PATH"] = pathlib.Path(os.path.dirname(os.path.abspath(__file__))).joinpath(entry.name)
|
||||
|
||||
plugin_import_print_string = "Found %s type plugin: %s %s. " % (curr_dict["TYPE"], curr_dict["NAME"], curr_dict["VERSION"])
|
||||
@ -32,7 +32,7 @@ for entry in os.scandir(plugins_top_dir):
|
||||
plugin_import_print_string += " ImportWarning: Missing PLUGIN_* Value."
|
||||
plugin_use = False
|
||||
|
||||
elif curr_dict["TYPE"] not in ["origin", "alt_epg"]:
|
||||
elif curr_dict["TYPE"] not in ["origin", "alt_epg", "alt_stream"]:
|
||||
plugin_use = False
|
||||
plugin_import_print_string += " ImportWarning: Invalid PLUGIN_TYPE."
|
||||
|
||||
@ -53,8 +53,16 @@ for entry in os.scandir(plugins_top_dir):
|
||||
if curr_dict["TYPE"] == "origin":
|
||||
imp_string = "from .%s import origin" % entry.name
|
||||
exec(imp_string)
|
||||
if curr_dict["TYPE"] == "alt_epg":
|
||||
imp_string = "from .%s import %sEPG" % (entry.name, curr_dict["NAME"])
|
||||
imp_string = "from .%s import %s_Setup" % (entry.name, curr_dict["NAME"].upper())
|
||||
try:
|
||||
exec(imp_string)
|
||||
except ImportError:
|
||||
pass
|
||||
elif curr_dict["TYPE"] == "alt_epg":
|
||||
imp_string = "from .%s import *" % entry.name
|
||||
exec(imp_string)
|
||||
elif curr_dict["TYPE"] == "alt_stream":
|
||||
imp_string = "from .%s import *" % entry.name
|
||||
exec(imp_string)
|
||||
|
||||
if not len([x for x in list(plugin_dict.keys()) if plugin_dict[x]["TYPE"] == "origin"]):
|
||||
|
||||
@ -7,6 +7,11 @@ PLUGIN_VERSION = "v0.6.0-beta"
|
||||
PLUGIN_TYPE = "alt_epg"
|
||||
|
||||
|
||||
class TVTV_Setup():
|
||||
def __init__(self, config):
|
||||
pass
|
||||
|
||||
|
||||
class tvtvEPG():
|
||||
|
||||
def __init__(self, fhdhr, channels):
|
||||
|
||||
@ -9,6 +9,11 @@ PLUGIN_VERSION = "v0.6.0-beta"
|
||||
PLUGIN_TYPE = "alt_epg"
|
||||
|
||||
|
||||
class ZAP2IT_Setup():
|
||||
def __init__(self, config):
|
||||
pass
|
||||
|
||||
|
||||
class zap2itEPG():
|
||||
|
||||
def __init__(self, fhdhr, channels):
|
||||
|
||||
@ -1,3 +1,8 @@
|
||||
PLUGIN_NAME = "NextPVR"
|
||||
PLUGIN_VERSION = "v0.6.0-beta"
|
||||
PLUGIN_TYPE = "origin"
|
||||
|
||||
|
||||
class NEXTPVR_Setup():
|
||||
def __init__(self, config):
|
||||
pass
|
||||
|
||||
@ -14,11 +14,6 @@
|
||||
"value": "fHDHR_NextPVR",
|
||||
"config_file": false,
|
||||
"config_web": false
|
||||
},
|
||||
"required":{
|
||||
"value": "nextpvr/pin",
|
||||
"config_file": false,
|
||||
"config_web": false
|
||||
}
|
||||
},
|
||||
"fhdhr":{
|
||||
@ -38,11 +33,6 @@
|
||||
"value": "origin",
|
||||
"config_file": true,
|
||||
"config_web": true
|
||||
},
|
||||
"valid_epg_methods":{
|
||||
"value": "None,blocks,origin,zap2it,tvtv",
|
||||
"config_file": false,
|
||||
"config_web": false
|
||||
}
|
||||
},
|
||||
"nextpvr":{
|
||||
@ -65,7 +55,8 @@
|
||||
"value": "none",
|
||||
"config_file": true,
|
||||
"config_web": true,
|
||||
"config_web_hidden": true
|
||||
"config_web_hidden": true,
|
||||
"required": true
|
||||
},
|
||||
"sid":{
|
||||
"value": "none",
|
||||
|
||||
@ -3,6 +3,30 @@ import subprocess
|
||||
|
||||
# from fHDHR.exceptions import TunerError
|
||||
|
||||
PLUGIN_NAME = "ffmpeg"
|
||||
PLUGIN_VERSION = "v0.6.0-beta"
|
||||
PLUGIN_TYPE = "alt_stream"
|
||||
|
||||
|
||||
class FFMPEG_Setup():
|
||||
def __init__(self, config):
|
||||
try:
|
||||
ffmpeg_command = [config.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_proc.kill()
|
||||
ffmpeg_version = ffmpeg_version.decode().split("version ")[1].split(" ")[0]
|
||||
except FileNotFoundError:
|
||||
ffmpeg_version = "Missing"
|
||||
print("Failed to find ffmpeg.")
|
||||
config.register_version("ffmpeg", ffmpeg_version)
|
||||
|
||||
|
||||
class FFMPEG_Stream():
|
||||
|
||||
9
plugins/fHDHR_plugin_stream_ffmpeg/ffmpeg_conf.json
Normal file
9
plugins/fHDHR_plugin_stream_ffmpeg/ffmpeg_conf.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"ffmpeg":{
|
||||
"path":{
|
||||
"value": "ffmpeg",
|
||||
"config_file": true,
|
||||
"config_web": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3,6 +3,30 @@ import subprocess
|
||||
|
||||
# from fHDHR.exceptions import TunerError
|
||||
|
||||
PLUGIN_NAME = "vlc"
|
||||
PLUGIN_VERSION = "v0.6.0-beta"
|
||||
PLUGIN_TYPE = "alt_stream"
|
||||
|
||||
|
||||
class VLC_Setup():
|
||||
def __init__(self, config):
|
||||
try:
|
||||
vlc_command = [config.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_proc.kill()
|
||||
vlc_version = vlc_version.decode().split("version ")[1].split('\n')[0]
|
||||
except FileNotFoundError:
|
||||
vlc_version = "Missing"
|
||||
print("Failed to find vlc.")
|
||||
config.register_version("vlc", vlc_version)
|
||||
|
||||
|
||||
class VLC_Stream():
|
||||
|
||||
9
plugins/fHDHR_plugin_stream_vlc/vlc_conf.json
Normal file
9
plugins/fHDHR_plugin_stream_vlc/vlc_conf.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"vlc":{
|
||||
"path":{
|
||||
"value": "cvlc",
|
||||
"config_file": true,
|
||||
"config_web": true
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user