1
0
mirror of https://github.com/fHDHR/fHDHR_NextPVR.git synced 2025-12-06 06:56:57 -05:00

Compare commits

..

6 Commits

Author SHA1 Message Date
Deathbybandaid
13faf0845e
Merge pull request #150 from deathbybandaid/dev
Strip invalid Config Options
2021-01-23 18:52:16 -05:00
deathbybandaid
1cf2a7acce Strip invalid Config Options 2021-01-23 18:50:51 -05:00
Deathbybandaid
36712e7ba0
Merge pull request #149 from deathbybandaid/dev
Update CSS styling
2021-01-23 18:31:48 -05:00
deathbybandaid
02e825978b Update CSS styling 2021-01-23 18:30:24 -05:00
Deathbybandaid
9642feecae
Merge pull request #148 from deathbybandaid/dev
Make alt_stream methods into plugins and enhance Config system
2021-01-23 17:59:41 -05:00
deathbybandaid
b8ce4f4e8a Make alt_stream methods into plugins and enhance Config system 2021-01-23 17:50:14 -05:00
23 changed files with 294 additions and 259 deletions

View File

@ -24,11 +24,6 @@
"value": "fHDHR", "value": "fHDHR",
"config_file": false, "config_file": false,
"config_web": false "config_web": false
},
"required":{
"value": "none",
"config_file": false,
"config_web": false
} }
} }
} }

View File

@ -20,19 +20,5 @@
"config_file": true, "config_file": true,
"config_web": true "config_web": true
} }
}, }
"ffmpeg":{
"path":{
"value": "ffmpeg",
"config_file": true,
"config_web": true
}
},
"vlc":{
"path":{
"value": "cvlc",
"config_file": true,
"config_web": true
}
}
} }

View File

@ -3,7 +3,6 @@ import sys
import random import random
import configparser import configparser
import pathlib import pathlib
import subprocess
import platform import platform
import json import json
@ -23,21 +22,20 @@ class Config():
self.dict = {} self.dict = {}
self.config_file = filename self.config_file = filename
self.initial_load(script_dir) self.core_setup(script_dir)
self.plugins_setup()
self.user_config()
self.config_verification() self.config_verification()
def initial_load(self, script_dir): def core_setup(self, script_dir):
data_dir = pathlib.Path(script_dir).joinpath('data') data_dir = pathlib.Path(script_dir).joinpath('data')
fHDHR_web_dir = pathlib.Path(script_dir).joinpath('fHDHR_web') fHDHR_web_dir = pathlib.Path(script_dir).joinpath('fHDHR_web')
www_dir = pathlib.Path(fHDHR_web_dir).joinpath('www_dir') 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"] = { self.internal["paths"] = {
"script_dir": script_dir, "script_dir": script_dir,
"data_dir": data_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'), "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'),
"fHDHR_web_dir": fHDHR_web_dir, "fHDHR_web_dir": fHDHR_web_dir,
@ -56,15 +54,26 @@ class Config():
if str(file_item_path).endswith("_conf.json"): if str(file_item_path).endswith("_conf.json"):
self.read_json_config(file_item_path) 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": if dir_type == "origin":
dir_tops = [self.internal["paths"]["origin"]] dir_tops = [self.internal["paths"]["origin"]]
elif dir_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"] == "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 top_dir in dir_tops:
for file_item in os.listdir(top_dir): for file_item in os.listdir(top_dir):
file_item_path = pathlib.Path(top_dir).joinpath(file_item) file_item_path = pathlib.Path(top_dir).joinpath(file_item)
if file_item_path.is_dir(): if file_item_path.is_dir():
@ -76,22 +85,33 @@ class Config():
if str(file_item_path).endswith("_conf.json"): if str(file_item_path).endswith("_conf.json"):
self.read_json_config(file_item_path) self.read_json_config(file_item_path)
print("Loading Configuration File: %s" % self.config_file) # Rename the Origin conf section
self.read_ini_config(self.config_file) 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): def load_versions(self):
self.internal["versions"] = {} self.internal["versions"] = {}
self.internal["versions"]["fHDHR"] = fHDHR_VERSION self.internal["versions"]["fHDHR"] = fHDHR_VERSION
self.internal["versions"]["fHDHR_web"] = self.fHDHR_web.fHDHR_web_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 self.internal["versions"]["Python"] = sys.version
opersystem = platform.system() opersystem = platform.system()
@ -110,180 +130,26 @@ class Config():
isdocker = is_docker() isdocker = is_docker()
self.internal["versions"]["Docker"] = isdocker self.internal["versions"]["Docker"] = isdocker
if self.dict["streaming"]["method"] == "ffmpeg": def user_config(self):
try: print("Loading Configuration File: %s" % self.config_file)
ffmpeg_command = [self.dict["ffmpeg"]["path"], self.read_ini_config(self.config_file)
"-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 config_verification(self): def config_verification(self):
if self.dict["main"]["required"]: required_missing = {}
required_missing = [] # create dict and combine items
if isinstance(self.dict["main"]["required"], str): for config_section in list(self.conf_default.keys()):
self.dict["main"]["required"] = [self.dict["main"]["required"]] for config_item in list(self.conf_default[config_section].keys()):
if len(self.dict["main"]["required"]): if self.conf_default[config_section][config_item]["required"]:
for req_item in self.dict["main"]["required"]: config_section_name = config_section
req_section = req_item.split("/")[0] if config_section == self.dict["main"]["dictpopname"]:
req_key = req_item.split("/")[1] config_section_name = "origin"
if not self.dict[req_section][req_key]: if not self.dict[config_section_name][config_item]:
required_missing.append(req_item) if config_section not in list(required_missing.keys()):
if len(required_missing): required_missing[config_section] = []
raise fHDHR.exceptions.ConfigurationError("Required configuration options missing: %s" % ", ".join(required_missing)) required_missing[config_section].append(config_item)
for config_section in list(required_missing.keys()):
self.dict["origin"] = self.dict.pop(self.dict["main"]["dictpopname"]) print("Warning! Required configuration options missing: [%s]%s" % (config_section, ", ".join(required_missing[config_section])))
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])
if self.dict["epg"]["method"] and self.dict["epg"]["method"] not in ["None"]: if self.dict["epg"]["method"] and self.dict["epg"]["method"] not in ["None"]:
if isinstance(self.dict["epg"]["method"], str): if isinstance(self.dict["epg"]["method"], str):
@ -294,7 +160,7 @@ class Config():
epg_methods.append("origin") epg_methods.append("origin")
elif epg_method in ["None"]: elif epg_method in ["None"]:
raise fHDHR.exceptions.ConfigurationError("Invalid EPG Method. Exiting...") 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) epg_methods.append(epg_method)
else: else:
raise fHDHR.exceptions.ConfigurationError("Invalid EPG Method. Exiting...") 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') 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...") raise fHDHR.exceptions.ConfigurationError("Invalid stream type. Exiting...")
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":
@ -325,6 +191,114 @@ class Config():
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":
self.dict["fhdhr"]["discovery_address"] = None 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): def __getattr__(self, name):
''' will only get called for undefined attributes ''' ''' will only get called for undefined attributes '''
if name in list(self.dict.keys()): if name in list(self.dict.keys()):

View File

@ -14,7 +14,7 @@ class fHDHR_Device():
self.epg = EPG(fhdhr, self.channels, originwrapper, plugins) 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) self.images = imageHandler(fhdhr, self.epg)

View File

@ -19,7 +19,7 @@ class EPG():
self.epgdict = {} self.epgdict = {}
self.epg_methods = self.fhdhr.config.dict["epg"]["method"] 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.blocks = blocksEPG(self.fhdhr, self.channels)
self.epg_handling = { self.epg_handling = {
@ -46,7 +46,7 @@ class EPG():
if not method: if not method:
method = self.def_method method = self.def_method
if (method == self.fhdhr.config.dict["main"]["dictpopname"] or 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" method = "origin"
epgtypename = method epgtypename = method
@ -92,7 +92,7 @@ class EPG():
if not method: if not method:
method = self.def_method method = self.def_method
if (method == self.fhdhr.config.dict["main"]["dictpopname"] or 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" method = "origin"
channel_guide_dict = {} channel_guide_dict = {}
@ -121,7 +121,7 @@ class EPG():
if not method: if not method:
method = self.def_method method = self.def_method
if (method == self.fhdhr.config.dict["main"]["dictpopname"] or 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" method = "origin"
if method in list(self.epgdict.keys()): if method in list(self.epgdict.keys()):
@ -160,7 +160,7 @@ class EPG():
def update(self, method=None): def update(self, method=None):
if (not method or 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 method = self.def_method
if method == self.fhdhr.config.dict["main"]["dictpopname"]: if method == self.fhdhr.config.dict["main"]["dictpopname"]:

View File

@ -7,9 +7,10 @@ from .tuner import Tuner
class Tuners(): class Tuners():
def __init__(self, fhdhr, epg, channels): def __init__(self, fhdhr, epg, channels, plugins):
self.fhdhr = fhdhr self.fhdhr = fhdhr
self.channels = channels self.channels = channels
self.plugins = plugins
self.epg = epg self.epg = epg
self.max_tuners = int(self.fhdhr.config.dict["fhdhr"]["tuner_count"]) 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)) self.fhdhr.logger.info("Creating %s tuners." % str(self.max_tuners))
for i in range(0, 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): 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 return next(tunernum for tunernum in list(self.tuners.keys()) if not self.tuners[tunernum].tuner_lock.locked()) or None

View File

@ -2,26 +2,24 @@
from .direct_stream import Direct_Stream from .direct_stream import Direct_Stream
from .direct_m3u8_stream import Direct_M3U8_Stream from .direct_m3u8_stream import Direct_M3U8_Stream
from .ffmpeg_stream import FFMPEG_Stream
from .vlc_stream import VLC_Stream
class Stream(): class Stream():
def __init__(self, fhdhr, stream_args, tuner): def __init__(self, fhdhr, stream_args, tuner, plugins):
self.fhdhr = fhdhr self.fhdhr = fhdhr
self.stream_args = stream_args self.stream_args = stream_args
if stream_args["method"] == "ffmpeg": self.plugins = plugins
self.method = FFMPEG_Stream(fhdhr, stream_args, tuner)
if stream_args["method"] == "vlc": if stream_args["method"] == "direct":
self.method = VLC_Stream(fhdhr, stream_args, tuner) if self.stream_args["true_content_type"].startswith(tuple(["application/", "text/"])):
elif (stream_args["method"] == "direct" and self.method = Direct_M3U8_Stream(fhdhr, stream_args, tuner)
not self.stream_args["true_content_type"].startswith(tuple(["application/", "text/"]))): else:
self.method = Direct_Stream(fhdhr, stream_args, tuner) self.method = Direct_Stream(fhdhr, stream_args, tuner)
elif (stream_args["method"] == "direct" and else:
self.stream_args["true_content_type"].startswith(tuple(["application/", "text/"]))):
self.method = Direct_M3U8_Stream(fhdhr, stream_args, tuner) self.method = eval("self.plugins.%s_Stream(fhdhr, stream_args, tuner)" % stream_args["method"].upper())
def get(self): def get(self):
return self.method.get() return self.method.get()

View File

@ -8,8 +8,9 @@ from .stream import Stream
class Tuner(): class Tuner():
def __init__(self, fhdhr, inum, epg): def __init__(self, fhdhr, inum, epg, plugins):
self.fhdhr = fhdhr self.fhdhr = fhdhr
self.plugins = plugins
self.number = inum self.number = inum
self.epg = epg self.epg = epg
@ -76,7 +77,7 @@ class Tuner():
self.status = {"status": "Inactive"} self.status = {"status": "Inactive"}
def get_stream(self, stream_args, tuner): 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() return stream.get()
def set_status(self, stream_args): def set_status(self, stream_args):

View File

@ -23,7 +23,7 @@ class EPG():
method = request.args.get('method', default="get", type=str) method = request.args.get('method', default="get", type=str)
source = request.args.get('source', default=self.fhdhr.config.dict["epg"]["def_method"], 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 return "%s Invalid xmltv method" % source
redirect_url = request.args.get('redirect', default=None, type=str) redirect_url = request.args.get('redirect', default=None, type=str)

View File

@ -31,7 +31,7 @@ class Images():
elif method == "get": elif method == "get":
source = request.args.get('source', default=self.fhdhr.config.dict["epg"]["method"], type=str) 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) image_type = request.args.get('type', default="content", type=str)
if image_type in ["content", "channel"]: if image_type in ["content", "channel"]:
image_id = request.args.get('id', default=None, type=str) image_id = request.args.get('id', default=None, type=str)

View File

@ -31,7 +31,7 @@ class Tuners():
redirect_url = request.args.get('redirect', default=None, type=str) 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) channel_number = request.args.get('channel', None, type=str)
if not channel_number: if not channel_number:

View File

@ -38,7 +38,7 @@ class xmlTV():
method = request.args.get('method', default="get", type=str) method = request.args.get('method', default="get", type=str)
source = request.args.get('source', default=self.fhdhr.config.dict["epg"]["def_method"], 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 return "%s Invalid xmltv method" % source
redirect_url = request.args.get('redirect', default=None, type=str) redirect_url = request.args.get('redirect', default=None, type=str)

View File

@ -14,7 +14,7 @@
<th>Actions</th> <th>Actions</th>
</tr> </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"] %} {% if epg_method not in [None, "None"] %}
{% set epg_method_name = epg_method %} {% set epg_method_name = epg_method %}
{% if epg_method == "origin" %} {% if epg_method == "origin" %}

View File

@ -136,13 +136,13 @@ td {border: 1px solid black;}
/* Other options */ /* Other options */
.table-scroll.text-edit-cols td:nth-child(-n+4), .table-scroll.text-edit-cols td:nth-of-type(-n+4),
.table-scroll.text-edit-cols th:nth-child(-n+4){ .table-scroll.text-edit-cols th:nth-of-type(-n+4){
flex: 2 flex: 2
} }
.table-settings.text-edit-cols td:nth-child(-n+2), .table-settings.text-edit-cols td:nth-of-type(-n+2),
.table-settings.text-edit-cols th:nth-child(-n+2){ .table-settings.text-edit-cols th:nth-of-type(-n+2){
flex: 1; flex: 1;
} }

View File

@ -24,7 +24,7 @@ for entry in os.scandir(plugins_top_dir):
if curr_dict["TYPE"] == "origin": if curr_dict["TYPE"] == "origin":
curr_dict["PATH"] = pathlib.Path(os.path.dirname(os.path.abspath(__file__))).joinpath(entry.name).joinpath('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) 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"]) 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_import_print_string += " ImportWarning: Missing PLUGIN_* Value."
plugin_use = False 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_use = False
plugin_import_print_string += " ImportWarning: Invalid PLUGIN_TYPE." 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": if curr_dict["TYPE"] == "origin":
imp_string = "from .%s import origin" % entry.name imp_string = "from .%s import origin" % entry.name
exec(imp_string) exec(imp_string)
if curr_dict["TYPE"] == "alt_epg": imp_string = "from .%s import %s_Setup" % (entry.name, curr_dict["NAME"].upper())
imp_string = "from .%s import %sEPG" % (entry.name, curr_dict["NAME"]) 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) exec(imp_string)
if not len([x for x in list(plugin_dict.keys()) if plugin_dict[x]["TYPE"] == "origin"]): if not len([x for x in list(plugin_dict.keys()) if plugin_dict[x]["TYPE"] == "origin"]):

View File

@ -7,6 +7,11 @@ PLUGIN_VERSION = "v0.6.0-beta"
PLUGIN_TYPE = "alt_epg" PLUGIN_TYPE = "alt_epg"
class TVTV_Setup():
def __init__(self, config):
pass
class tvtvEPG(): class tvtvEPG():
def __init__(self, fhdhr, channels): def __init__(self, fhdhr, channels):

View File

@ -9,6 +9,11 @@ PLUGIN_VERSION = "v0.6.0-beta"
PLUGIN_TYPE = "alt_epg" PLUGIN_TYPE = "alt_epg"
class ZAP2IT_Setup():
def __init__(self, config):
pass
class zap2itEPG(): class zap2itEPG():
def __init__(self, fhdhr, channels): def __init__(self, fhdhr, channels):

View File

@ -1,3 +1,8 @@
PLUGIN_NAME = "NextPVR" PLUGIN_NAME = "NextPVR"
PLUGIN_VERSION = "v0.6.0-beta" PLUGIN_VERSION = "v0.6.0-beta"
PLUGIN_TYPE = "origin" PLUGIN_TYPE = "origin"
class NEXTPVR_Setup():
def __init__(self, config):
pass

View File

@ -14,11 +14,6 @@
"value": "fHDHR_NextPVR", "value": "fHDHR_NextPVR",
"config_file": false, "config_file": false,
"config_web": false "config_web": false
},
"required":{
"value": "nextpvr/pin",
"config_file": false,
"config_web": false
} }
}, },
"fhdhr":{ "fhdhr":{
@ -38,12 +33,7 @@
"value": "origin", "value": "origin",
"config_file": true, "config_file": true,
"config_web": true "config_web": true
}, }
"valid_epg_methods":{
"value": "None,blocks,origin,zap2it,tvtv",
"config_file": false,
"config_web": false
}
}, },
"nextpvr":{ "nextpvr":{
"address":{ "address":{
@ -65,7 +55,8 @@
"value": "none", "value": "none",
"config_file": true, "config_file": true,
"config_web": true, "config_web": true,
"config_web_hidden": true "config_web_hidden": true,
"required": true
}, },
"sid":{ "sid":{
"value": "none", "value": "none",

View File

@ -3,6 +3,30 @@ import subprocess
# from fHDHR.exceptions import TunerError # 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(): class FFMPEG_Stream():

View File

@ -0,0 +1,9 @@
{
"ffmpeg":{
"path":{
"value": "ffmpeg",
"config_file": true,
"config_web": true
}
}
}

View File

@ -3,6 +3,30 @@ import subprocess
# from fHDHR.exceptions import TunerError # 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(): class VLC_Stream():

View File

@ -0,0 +1,9 @@
{
"vlc":{
"path":{
"value": "cvlc",
"config_file": true,
"config_web": true
}
}
}