mirror of
https://github.com/fHDHR/fHDHR_NextPVR.git
synced 2025-12-06 15:26:57 -05:00
commit
295a7259ac
@ -1,2 +1,3 @@
|
|||||||
# pylama:ignore=W0401,W0611
|
# pylama:ignore=W0401,W0611
|
||||||
from .zap2it import *
|
from .zap2it import *
|
||||||
|
from .tvtv import *
|
||||||
|
|||||||
152
alternative_epg/tvtv/__init__.py
Normal file
152
alternative_epg/tvtv/__init__.py
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
import datetime
|
||||||
|
|
||||||
|
from fHDHR.exceptions import EPGSetupError
|
||||||
|
|
||||||
|
|
||||||
|
class tvtvEPG():
|
||||||
|
|
||||||
|
def __init__(self, fhdhr, channels):
|
||||||
|
self.fhdhr = fhdhr
|
||||||
|
|
||||||
|
self.channels = channels
|
||||||
|
|
||||||
|
@property
|
||||||
|
def postalcode(self):
|
||||||
|
if self.fhdhr.config.dict["tvtv"]["postalcode"]:
|
||||||
|
return self.fhdhr.config.dict["tvtv"]["postalcode"]
|
||||||
|
try:
|
||||||
|
postalcode_url = 'http://ipinfo.io/json'
|
||||||
|
postalcode_req = self.fhdhr.web.session.get(postalcode_url)
|
||||||
|
data = postalcode_req.json()
|
||||||
|
postalcode = data["postal"]
|
||||||
|
except Exception as e:
|
||||||
|
raise EPGSetupError("Unable to automatically optain postalcode: " + str(e))
|
||||||
|
postalcode = None
|
||||||
|
return postalcode
|
||||||
|
|
||||||
|
@property
|
||||||
|
def lineup_id(self):
|
||||||
|
lineup_id_url = "https://www.tvtv.us/tvm/t/tv/v4/lineups?postalCode=%s" % self.postalcode
|
||||||
|
if self.fhdhr.config.dict["tvtv"]["lineuptype"]:
|
||||||
|
lineup_id_url += "&lineupType=%s" % self.fhdhr.config.dict["tvtv"]["lineuptype"]
|
||||||
|
lineup_id_req = self.fhdhr.web.session.get(lineup_id_url)
|
||||||
|
data = lineup_id_req.json()
|
||||||
|
lineup_id = data[0]["lineupID"]
|
||||||
|
return lineup_id
|
||||||
|
|
||||||
|
def update_epg(self):
|
||||||
|
programguide = {}
|
||||||
|
|
||||||
|
# Make a date range to pull
|
||||||
|
todaydate = datetime.date.today()
|
||||||
|
dates_to_pull = []
|
||||||
|
for x in range(-1, 6):
|
||||||
|
datesdict = {
|
||||||
|
"start": todaydate + datetime.timedelta(days=x),
|
||||||
|
"stop": todaydate + datetime.timedelta(days=x+1)
|
||||||
|
}
|
||||||
|
dates_to_pull.append(datesdict)
|
||||||
|
|
||||||
|
self.remove_stale_cache(todaydate)
|
||||||
|
|
||||||
|
cached_items = self.get_cached(dates_to_pull)
|
||||||
|
for result in cached_items:
|
||||||
|
|
||||||
|
for chan_item in result:
|
||||||
|
|
||||||
|
channel_number = "%s.%s" % (chan_item["channel"]['channelNumber'], chan_item["channel"]['subChannelNumber'])
|
||||||
|
|
||||||
|
if str(channel_number) not in list(programguide.keys()):
|
||||||
|
|
||||||
|
programguide[channel_number] = {
|
||||||
|
"callsign": chan_item["channel"]["callsign"],
|
||||||
|
"name": chan_item["channel"]["name"],
|
||||||
|
"number": channel_number,
|
||||||
|
"id": str(chan_item["channel"]["stationID"]),
|
||||||
|
"thumbnail": "https://cdn.tvpassport.com/image/station/100x100/%s" % chan_item["channel"]["logoFilename"],
|
||||||
|
"listing": [],
|
||||||
|
}
|
||||||
|
for listing in chan_item["listings"]:
|
||||||
|
|
||||||
|
timestamp = self.tvtv_timestamps(listing["listDateTime"], listing["duration"])
|
||||||
|
|
||||||
|
clean_prog_dict = {
|
||||||
|
"time_start": timestamp['time_start'],
|
||||||
|
"time_end": timestamp['time_end'],
|
||||||
|
"duration_minutes": listing["duration"],
|
||||||
|
"thumbnail": "https://cdn.tvpassport.com/image/show/480x720/%s" % listing["artwork"]["poster"],
|
||||||
|
"title": listing["showName"],
|
||||||
|
"sub-title": listing["episodeTitle"],
|
||||||
|
"description": listing["description"],
|
||||||
|
"rating": listing["rating"],
|
||||||
|
"episodetitle": listing["episodeTitle"],
|
||||||
|
"releaseyear": listing["year"],
|
||||||
|
"genres": [],
|
||||||
|
"seasonnumber": None,
|
||||||
|
"episodenumber": None,
|
||||||
|
"isnew": listing["new"],
|
||||||
|
"id": listing["listingID"],
|
||||||
|
}
|
||||||
|
|
||||||
|
if not any(d['id'] == clean_prog_dict['id'] for d in programguide[channel_number]["listing"]):
|
||||||
|
programguide[channel_number]["listing"].append(clean_prog_dict)
|
||||||
|
|
||||||
|
return programguide
|
||||||
|
|
||||||
|
def tvtv_timestamps(self, starttime, duration):
|
||||||
|
start_time = datetime.datetime.strptime(starttime, '%Y-%m-%d %H:%M:%S')
|
||||||
|
end_time = start_time + datetime.timedelta(minutes=duration)
|
||||||
|
start_time = start_time.strftime('%Y%m%d%H%M%S +0000')
|
||||||
|
end_time = end_time.strftime('%Y%m%d%H%M%S +0000')
|
||||||
|
timestamp = {
|
||||||
|
"time_start": start_time,
|
||||||
|
"time_end": end_time
|
||||||
|
}
|
||||||
|
return timestamp
|
||||||
|
|
||||||
|
def get_cached(self, dates_to_pull):
|
||||||
|
for datesdict in dates_to_pull:
|
||||||
|
starttime = str(datesdict["start"]) + "T00%3A00%3A00.000Z"
|
||||||
|
stoptime = str(datesdict["stop"]) + "T00%3A00%3A00.000Z"
|
||||||
|
url = "https://www.tvtv.us/tvm/t/tv/v4/lineups/%s/listings/grid?start=%s&end=%s" % (self.lineup_id, starttime, stoptime)
|
||||||
|
self.get_cached_item(str(datesdict["start"]), url)
|
||||||
|
cache_list = self.fhdhr.db.get_cacheitem_value("cache_list", "offline_cache", "tvtv") or []
|
||||||
|
return [self.fhdhr.db.get_cacheitem_value(x, "offline_cache", "tvtv") for x in cache_list]
|
||||||
|
|
||||||
|
def get_cached_item(self, cache_key, url):
|
||||||
|
cacheitem = self.fhdhr.db.get_cacheitem_value(cache_key, "offline_cache", "tvtv")
|
||||||
|
if cacheitem:
|
||||||
|
self.fhdhr.logger.info('FROM CACHE: ' + str(cache_key))
|
||||||
|
return cacheitem
|
||||||
|
else:
|
||||||
|
self.fhdhr.logger.info('Fetching: ' + url)
|
||||||
|
try:
|
||||||
|
resp = self.fhdhr.web.session.get(url)
|
||||||
|
except self.fhdhr.web.exceptions.HTTPError:
|
||||||
|
self.fhdhr.logger.info('Got an error! Ignoring it.')
|
||||||
|
return
|
||||||
|
result = resp.json()
|
||||||
|
|
||||||
|
self.fhdhr.db.set_cacheitem_value(cache_key, "offline_cache", result, "tvtv")
|
||||||
|
cache_list = self.fhdhr.db.get_cacheitem_value("cache_list", "offline_cache", "tvtv") or []
|
||||||
|
cache_list.append(cache_key)
|
||||||
|
self.fhdhr.db.set_cacheitem_value("cache_list", "offline_cache", cache_list, "tvtv")
|
||||||
|
|
||||||
|
def remove_stale_cache(self, todaydate):
|
||||||
|
cache_list = self.fhdhr.db.get_cacheitem_value("cache_list", "offline_cache", "tvtv") or []
|
||||||
|
cache_to_kill = []
|
||||||
|
for cacheitem in cache_list:
|
||||||
|
cachedate = datetime.datetime.strptime(str(cacheitem), "%Y-%m-%d")
|
||||||
|
todaysdate = datetime.datetime.strptime(str(todaydate), "%Y-%m-%d")
|
||||||
|
if cachedate < todaysdate:
|
||||||
|
cache_to_kill.append(cacheitem)
|
||||||
|
self.fhdhr.db.delete_cacheitem_value(cacheitem, "offline_cache", "tvtv")
|
||||||
|
self.fhdhr.logger.info('Removing stale cache: ' + str(cacheitem))
|
||||||
|
self.fhdhr.db.set_cacheitem_value("cache_list", "offline_cache", [x for x in cache_list if x not in cache_to_kill], "tvtv")
|
||||||
|
|
||||||
|
def clear_cache(self):
|
||||||
|
cache_list = self.fhdhr.db.get_cacheitem_value("cache_list", "offline_cache", "tvtv") or []
|
||||||
|
for cacheitem in cache_list:
|
||||||
|
self.fhdhr.db.delete_cacheitem_value(cacheitem, "offline_cache", "tvtv")
|
||||||
|
self.fhdhr.logger.info('Removing cache: ' + str(cacheitem))
|
||||||
|
self.fhdhr.db.delete_cacheitem_value("cache_list", "offline_cache", "tvtv")
|
||||||
14
alternative_epg/tvtv/tvtv_conf.json
Normal file
14
alternative_epg/tvtv/tvtv_conf.json
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"tvtv":{
|
||||||
|
"postalcode":{
|
||||||
|
"value": "none",
|
||||||
|
"config_file": true,
|
||||||
|
"config_web": false
|
||||||
|
},
|
||||||
|
"lineuptype":{
|
||||||
|
"value": "none",
|
||||||
|
"config_file": true,
|
||||||
|
"config_web": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -12,19 +12,19 @@ class zap2itEPG():
|
|||||||
|
|
||||||
self.channels = channels
|
self.channels = channels
|
||||||
|
|
||||||
self.postalcode = self.fhdhr.config.dict["zap2it"]["postalcode"]
|
@property
|
||||||
|
def postalcode(self):
|
||||||
def get_location(self):
|
if self.fhdhr.config.dict["zap2it"]["postalcode"]:
|
||||||
self.fhdhr.logger.warning("Zap2it postalcode not set, attempting to retrieve.")
|
return self.fhdhr.config.dict["zap2it"]["postalcode"]
|
||||||
if not self.postalcode:
|
try:
|
||||||
try:
|
postalcode_url = 'http://ipinfo.io/json'
|
||||||
postalcode_url = 'http://ipinfo.io/json'
|
postalcode_req = self.fhdhr.web.session.get(postalcode_url)
|
||||||
postalcode_req = self.fhdhr.web.session.get(postalcode_url)
|
data = postalcode_req.json()
|
||||||
data = postalcode_req.json()
|
postalcode = data["postal"]
|
||||||
self.postalcode = data["postal"]
|
except Exception as e:
|
||||||
except Exception as e:
|
raise EPGSetupError("Unable to automatically optain postalcode: " + str(e))
|
||||||
raise EPGSetupError("Unable to automatically optain zap2it postalcode: " + str(e))
|
postalcode = None
|
||||||
return self.postalcode
|
return postalcode
|
||||||
|
|
||||||
def update_epg(self):
|
def update_epg(self):
|
||||||
programguide = {}
|
programguide = {}
|
||||||
@ -119,7 +119,7 @@ class zap2itEPG():
|
|||||||
'timespan': self.fhdhr.config.dict["zap2it"]['timespan'],
|
'timespan': self.fhdhr.config.dict["zap2it"]['timespan'],
|
||||||
'timezone': self.fhdhr.config.dict["zap2it"]['timezone'],
|
'timezone': self.fhdhr.config.dict["zap2it"]['timezone'],
|
||||||
'userId': self.fhdhr.config.dict["zap2it"]['userid'],
|
'userId': self.fhdhr.config.dict["zap2it"]['userid'],
|
||||||
'postalCode': str(self.postalcode or self.get_location()),
|
'postalCode': str(self.postalcode),
|
||||||
'lineupId': '%s-%s-DEFAULT' % (self.fhdhr.config.dict["zap2it"]['country'], self.fhdhr.config.dict["zap2it"]['device']),
|
'lineupId': '%s-%s-DEFAULT' % (self.fhdhr.config.dict["zap2it"]['country'], self.fhdhr.config.dict["zap2it"]['device']),
|
||||||
'time': i_time,
|
'time': i_time,
|
||||||
'Activity_ID': 1,
|
'Activity_ID': 1,
|
||||||
@ -32,12 +32,14 @@ class Config():
|
|||||||
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 = pathlib.Path(script_dir).joinpath('origin')
|
||||||
|
|
||||||
self.internal["paths"] = {
|
self.internal["paths"] = {
|
||||||
"script_dir": script_dir,
|
"script_dir": script_dir,
|
||||||
"data_dir": data_dir,
|
"data_dir": data_dir,
|
||||||
"alternative_epg": pathlib.Path(script_dir).joinpath('alternative_epg'),
|
"alternative_epg": pathlib.Path(script_dir).joinpath('alternative_epg'),
|
||||||
"origin": pathlib.Path(script_dir).joinpath('origin'),
|
"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'),
|
||||||
"www_dir": www_dir,
|
"www_dir": www_dir,
|
||||||
@ -53,9 +55,15 @@ class Config():
|
|||||||
for dir_type in ["alternative_epg", "origin"]:
|
for dir_type in ["alternative_epg", "origin"]:
|
||||||
|
|
||||||
for file_item in os.listdir(self.internal["paths"][dir_type]):
|
for file_item in os.listdir(self.internal["paths"][dir_type]):
|
||||||
file_item_path = os.path.join(self.internal["paths"][dir_type], file_item)
|
file_item_path = pathlib.Path(self.internal["paths"][dir_type]).joinpath(file_item)
|
||||||
if str(file_item_path).endswith("_conf.json"):
|
if file_item_path.is_dir():
|
||||||
self.read_json_config(file_item_path)
|
for sub_file_item in os.listdir(file_item_path):
|
||||||
|
sub_file_item_path = pathlib.Path(file_item_path).joinpath(sub_file_item)
|
||||||
|
if str(sub_file_item_path).endswith("_conf.json"):
|
||||||
|
self.read_json_config(sub_file_item_path)
|
||||||
|
else:
|
||||||
|
if str(file_item_path).endswith("_conf.json"):
|
||||||
|
self.read_json_config(file_item_path)
|
||||||
|
|
||||||
print("Loading Configuration File: " + str(self.config_file))
|
print("Loading Configuration File: " + str(self.config_file))
|
||||||
self.read_ini_config(self.config_file)
|
self.read_ini_config(self.config_file)
|
||||||
|
|||||||
@ -67,7 +67,7 @@ class fHDHR_Cluster():
|
|||||||
self.fhdhr.logger.info("Found %s clustered services." % str(len(list(cluster.keys()))))
|
self.fhdhr.logger.info("Found %s clustered services." % str(len(list(cluster.keys()))))
|
||||||
for location in list(cluster.keys()):
|
for location in list(cluster.keys()):
|
||||||
if location != self.fhdhr.api.base:
|
if location != self.fhdhr.api.base:
|
||||||
self.fhdhr.logger.info("Checking Cluster Syncronization information from %s." % location)
|
self.fhdhr.logger.debug("Checking Cluster Syncronization information from %s." % location)
|
||||||
sync_url = location + "/api/cluster?method=get"
|
sync_url = location + "/api/cluster?method=get"
|
||||||
try:
|
try:
|
||||||
sync_open = self.fhdhr.web.session.get(sync_url)
|
sync_open = self.fhdhr.web.session.get(sync_url)
|
||||||
|
|||||||
@ -140,6 +140,9 @@ class EPG():
|
|||||||
if entry.is_file():
|
if entry.is_file():
|
||||||
if entry.name[0] != '_' and entry.name.endswith(".py"):
|
if entry.name[0] != '_' and entry.name.endswith(".py"):
|
||||||
new_epgtype_list.append(str(entry.name[:-3]))
|
new_epgtype_list.append(str(entry.name[:-3]))
|
||||||
|
elif entry.is_dir():
|
||||||
|
if entry.name[0] != '_':
|
||||||
|
new_epgtype_list.append(str(entry.name))
|
||||||
for method in new_epgtype_list:
|
for method in new_epgtype_list:
|
||||||
self.fhdhr.logger.info("Found %s EPG method." % method)
|
self.fhdhr.logger.info("Found %s EPG method." % method)
|
||||||
self.epg_handling[method] = eval("self.alternative_epg.%s.%sEPG(self.fhdhr, self.channels)" % (method, method))
|
self.epg_handling[method] = eval("self.alternative_epg.%s.%sEPG(self.fhdhr, self.channels)" % (method, method))
|
||||||
|
|||||||
@ -1,27 +1,9 @@
|
|||||||
|
from .origin_channels_standin import OriginChannels_StandIN
|
||||||
|
from .origin_epg_standin import OriginEPG_StandIN
|
||||||
|
|
||||||
import fHDHR.exceptions
|
import fHDHR.exceptions
|
||||||
|
|
||||||
|
|
||||||
class OriginEPG_StandIN():
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def update_epg(self, channels):
|
|
||||||
return {}
|
|
||||||
|
|
||||||
|
|
||||||
class OriginChannels_StandIN():
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def get_channels(self):
|
|
||||||
return []
|
|
||||||
|
|
||||||
def get_channel_stream(self, chandict):
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
class OriginServiceWrapper():
|
class OriginServiceWrapper():
|
||||||
|
|
||||||
def __init__(self, fhdhr, origin):
|
def __init__(self, fhdhr, origin):
|
||||||
@ -40,6 +22,7 @@ class OriginServiceWrapper():
|
|||||||
self.setup_success = True
|
self.setup_success = True
|
||||||
self.fhdhr.logger.info("%s Setup Success" % self.servicename)
|
self.fhdhr.logger.info("%s Setup Success" % self.servicename)
|
||||||
except fHDHR.exceptions.OriginSetupError as e:
|
except fHDHR.exceptions.OriginSetupError as e:
|
||||||
|
self.originservice = None
|
||||||
self.fhdhr.logger.error(e)
|
self.fhdhr.logger.error(e)
|
||||||
self.setup_success = False
|
self.setup_success = False
|
||||||
|
|
||||||
@ -59,25 +42,6 @@ class OriginServiceWrapper():
|
|||||||
def update_epg(self, channels):
|
def update_epg(self, channels):
|
||||||
return self.epg.update_epg(channels)
|
return self.epg.update_epg(channels)
|
||||||
|
|
||||||
def get_status_dict(self):
|
|
||||||
|
|
||||||
if self.setup_success:
|
|
||||||
status_dict = {
|
|
||||||
"Setup": "Success",
|
|
||||||
}
|
|
||||||
|
|
||||||
try:
|
|
||||||
full_status_dict = self.origin.get_status_dict()
|
|
||||||
for status_key in list(full_status_dict.keys()):
|
|
||||||
status_dict[status_key] = full_status_dict[status_key]
|
|
||||||
return status_dict
|
|
||||||
except AttributeError:
|
|
||||||
return status_dict
|
|
||||||
else:
|
|
||||||
return {
|
|
||||||
"Setup": "Failed",
|
|
||||||
}
|
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
''' will only get called for undefined attributes '''
|
''' will only get called for undefined attributes '''
|
||||||
if hasattr(self.fhdhr, name):
|
if hasattr(self.fhdhr, name):
|
||||||
|
|||||||
11
fHDHR/originwrapper/origin_channels_standin.py
Normal file
11
fHDHR/originwrapper/origin_channels_standin.py
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
|
||||||
|
class OriginChannels_StandIN():
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_channels(self):
|
||||||
|
return []
|
||||||
|
|
||||||
|
def get_channel_stream(self, chandict):
|
||||||
|
return None
|
||||||
8
fHDHR/originwrapper/origin_epg_standin.py
Normal file
8
fHDHR/originwrapper/origin_epg_standin.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
|
||||||
|
class OriginEPG_StandIN():
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def update_epg(self, channels):
|
||||||
|
return {}
|
||||||
@ -43,6 +43,10 @@ class fHDHR_HTTP_Server():
|
|||||||
self.api = fHDHR_API(fhdhr)
|
self.api = fHDHR_API(fhdhr)
|
||||||
self.add_endpoints(self.api, "api")
|
self.add_endpoints(self.api, "api")
|
||||||
|
|
||||||
|
self.fhdhr.logger.info("Loading HTTP Origin Endpoints.")
|
||||||
|
self.origin_endpoints = self.fhdhr.originwrapper.origin.origin_web.fHDHR_Origin_Web(fhdhr)
|
||||||
|
self.add_endpoints(self.origin_endpoints, "origin_endpoints")
|
||||||
|
|
||||||
self.app.before_request(self.before_request)
|
self.app.before_request(self.before_request)
|
||||||
self.app.after_request(self.after_request)
|
self.app.after_request(self.after_request)
|
||||||
self.app.before_first_request(self.before_first_request)
|
self.app.before_first_request(self.before_first_request)
|
||||||
@ -69,7 +73,7 @@ class fHDHR_HTTP_Server():
|
|||||||
endpoint_methods = eval("self." + str(index_name) + "." + str(item) + ".endpoint_methods")
|
endpoint_methods = eval("self." + str(index_name) + "." + str(item) + ".endpoint_methods")
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
endpoint_methods = ['GET']
|
endpoint_methods = ['GET']
|
||||||
self.fhdhr.logger.info("Adding endpoint %s available at %s with %s methods." % (endpoint_name, ",".join(endpoints), ",".join(endpoint_methods)))
|
self.fhdhr.logger.debug("Adding endpoint %s available at %s with %s methods." % (endpoint_name, ",".join(endpoints), ",".join(endpoint_methods)))
|
||||||
for endpoint in endpoints:
|
for endpoint in endpoints:
|
||||||
self.add_endpoint(endpoint=endpoint,
|
self.add_endpoint(endpoint=endpoint,
|
||||||
endpoint_name=endpoint_name,
|
endpoint_name=endpoint_name,
|
||||||
|
|||||||
@ -28,15 +28,16 @@ class EPG():
|
|||||||
if method == "get":
|
if method == "get":
|
||||||
|
|
||||||
epgdict = self.fhdhr.device.epg.get_epg(source)
|
epgdict = self.fhdhr.device.epg.get_epg(source)
|
||||||
epgdict = epgdict.copy()
|
if source in ["blocks", "origin", self.fhdhr.config.dict["main"]["dictpopname"]]:
|
||||||
for c in list(epgdict.keys()):
|
epgdict = epgdict.copy()
|
||||||
chan_obj = self.fhdhr.device.channels.get_channel_obj("origin_id", epgdict[c]["id"])
|
for c in list(epgdict.keys()):
|
||||||
epgdict[chan_obj.dict["number"]] = epgdict.pop(c)
|
chan_obj = self.fhdhr.device.channels.get_channel_obj("origin_id", epgdict[c]["id"])
|
||||||
epgdict[chan_obj.dict["number"]]["name"] = chan_obj.dict["name"]
|
epgdict[chan_obj.dict["number"]] = epgdict.pop(c)
|
||||||
epgdict[chan_obj.dict["number"]]["callsign"] = chan_obj.dict["callsign"]
|
epgdict[chan_obj.dict["number"]]["name"] = chan_obj.dict["name"]
|
||||||
epgdict[chan_obj.dict["number"]]["number"] = chan_obj.dict["number"]
|
epgdict[chan_obj.dict["number"]]["callsign"] = chan_obj.dict["callsign"]
|
||||||
epgdict[chan_obj.dict["number"]]["id"] = chan_obj.dict["origin_id"]
|
epgdict[chan_obj.dict["number"]]["number"] = chan_obj.dict["number"]
|
||||||
epgdict[chan_obj.dict["number"]]["thumbnail"] = chan_obj.thumbnail
|
epgdict[chan_obj.dict["number"]]["id"] = chan_obj.dict["origin_id"]
|
||||||
|
epgdict[chan_obj.dict["number"]]["thumbnail"] = chan_obj.thumbnail
|
||||||
|
|
||||||
epg_json = json.dumps(epgdict, indent=4)
|
epg_json = json.dumps(epgdict, indent=4)
|
||||||
|
|
||||||
|
|||||||
@ -38,6 +38,18 @@ class xmlTV():
|
|||||||
if method == "get":
|
if method == "get":
|
||||||
|
|
||||||
epgdict = self.fhdhr.device.epg.get_epg(source)
|
epgdict = self.fhdhr.device.epg.get_epg(source)
|
||||||
|
|
||||||
|
if source in ["blocks", "origin", self.fhdhr.config.dict["main"]["dictpopname"]]:
|
||||||
|
epgdict = epgdict.copy()
|
||||||
|
for c in list(epgdict.keys()):
|
||||||
|
chan_obj = self.fhdhr.device.channels.get_channel_obj("origin_id", epgdict[c]["id"])
|
||||||
|
epgdict[chan_obj.dict["number"]] = epgdict.pop(c)
|
||||||
|
epgdict[chan_obj.dict["number"]]["name"] = chan_obj.dict["name"]
|
||||||
|
epgdict[chan_obj.dict["number"]]["callsign"] = chan_obj.dict["callsign"]
|
||||||
|
epgdict[chan_obj.dict["number"]]["number"] = chan_obj.dict["number"]
|
||||||
|
epgdict[chan_obj.dict["number"]]["id"] = chan_obj.dict["origin_id"]
|
||||||
|
epgdict[chan_obj.dict["number"]]["thumbnail"] = chan_obj.thumbnail
|
||||||
|
|
||||||
xmltv_xml = self.create_xmltv(base_url, epgdict, source)
|
xmltv_xml = self.create_xmltv(base_url, epgdict, source)
|
||||||
|
|
||||||
return Response(status=200,
|
return Response(status=200,
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
|
|
||||||
|
|
||||||
from .index_html import Index_HTML
|
from .index_html import Index_HTML
|
||||||
from .origin_html import Origin_HTML
|
|
||||||
from .channels_html import Channels_HTML
|
from .channels_html import Channels_HTML
|
||||||
from .guide_html import Guide_HTML
|
from .guide_html import Guide_HTML
|
||||||
from .cluster_html import Cluster_HTML
|
from .cluster_html import Cluster_HTML
|
||||||
@ -19,7 +18,6 @@ class fHDHR_Pages():
|
|||||||
self.fhdhr = fhdhr
|
self.fhdhr = fhdhr
|
||||||
|
|
||||||
self.index_html = Index_HTML(fhdhr)
|
self.index_html = Index_HTML(fhdhr)
|
||||||
self.origin_html = Origin_HTML(fhdhr)
|
|
||||||
self.channels_html = Channels_HTML(fhdhr)
|
self.channels_html = Channels_HTML(fhdhr)
|
||||||
self.channels_editor = Channels_Editor_HTML(fhdhr)
|
self.channels_editor = Channels_Editor_HTML(fhdhr)
|
||||||
self.guide_html = Guide_HTML(fhdhr)
|
self.guide_html = Guide_HTML(fhdhr)
|
||||||
|
|||||||
@ -1,18 +0,0 @@
|
|||||||
from flask import request, render_template
|
|
||||||
|
|
||||||
|
|
||||||
class Origin_HTML():
|
|
||||||
endpoints = ["/origin", "/origin.html"]
|
|
||||||
endpoint_name = "page_origin_html"
|
|
||||||
|
|
||||||
def __init__(self, fhdhr):
|
|
||||||
self.fhdhr = fhdhr
|
|
||||||
|
|
||||||
def __call__(self, *args):
|
|
||||||
return self.get(*args)
|
|
||||||
|
|
||||||
def get(self, *args):
|
|
||||||
|
|
||||||
origin_status_dict = self.fhdhr.originwrapper.get_status_dict()
|
|
||||||
origin_status_dict["Total Channels"] = len(self.fhdhr.device.channels.list)
|
|
||||||
return render_template('origin.html', request=request, fhdhr=self.fhdhr, origin_status_dict=origin_status_dict, list=list)
|
|
||||||
@ -2,6 +2,7 @@
|
|||||||
from .origin_service import *
|
from .origin_service import *
|
||||||
from .origin_channels import *
|
from .origin_channels import *
|
||||||
from .origin_epg import *
|
from .origin_epg import *
|
||||||
|
from .origin_web import *
|
||||||
|
|
||||||
ORIGIN_NAME = "fHDHR_NextPVR"
|
ORIGIN_NAME = "fHDHR_Locast"
|
||||||
ORIGIN_VERSION = "v0.5.0-beta"
|
ORIGIN_VERSION = "v0.5.0-beta"
|
||||||
|
|||||||
@ -40,7 +40,7 @@
|
|||||||
"config_web": true
|
"config_web": true
|
||||||
},
|
},
|
||||||
"valid_epg_methods":{
|
"valid_epg_methods":{
|
||||||
"value": "None,blocks,origin,zap2it",
|
"value": "None,blocks,origin,zap2it,tvtv",
|
||||||
"config_file": false,
|
"config_file": false,
|
||||||
"config_web": false
|
"config_web": false
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,8 +30,8 @@ class OriginEPG():
|
|||||||
def update_epg(self, fhdhr_channels):
|
def update_epg(self, fhdhr_channels):
|
||||||
programguide = {}
|
programguide = {}
|
||||||
|
|
||||||
for fhdhr_id in list(self.channels.list.keys()):
|
for fhdhr_id in list(fhdhr_channels.list.keys()):
|
||||||
chan_obj = self.channels.list[fhdhr_id]
|
chan_obj = fhdhr_channels.list[fhdhr_id]
|
||||||
|
|
||||||
if str(chan_obj.dict['number']) not in list(programguide.keys()):
|
if str(chan_obj.dict['number']) not in list(programguide.keys()):
|
||||||
|
|
||||||
|
|||||||
@ -10,6 +10,12 @@ class OriginService():
|
|||||||
def __init__(self, fhdhr):
|
def __init__(self, fhdhr):
|
||||||
self.fhdhr = fhdhr
|
self.fhdhr = fhdhr
|
||||||
|
|
||||||
|
self.nextpvr_address = ('%s%s:%s' %
|
||||||
|
("https://" if self.fhdhr.config.dict["origin"]["ssl"] else "http://",
|
||||||
|
self.fhdhr.config.dict["origin"]["address"],
|
||||||
|
str(self.fhdhr.config.dict["origin"]["port"]),
|
||||||
|
))
|
||||||
|
|
||||||
self.login()
|
self.login()
|
||||||
|
|
||||||
def login(self):
|
def login(self):
|
||||||
@ -25,11 +31,7 @@ class OriginService():
|
|||||||
if self.fhdhr.config.dict["origin"]["sid"]:
|
if self.fhdhr.config.dict["origin"]["sid"]:
|
||||||
return self.fhdhr.config.dict["origin"]["sid"]
|
return self.fhdhr.config.dict["origin"]["sid"]
|
||||||
|
|
||||||
initiate_url = ('%s%s:%s/service?method=session.initiate&ver=1.0&device=fhdhr' %
|
initiate_url = '%s/service?method=session.initiate&ver=1.0&device=fhdhr' % self.nextpvr_address
|
||||||
("https://" if self.fhdhr.config.dict["origin"]["ssl"] else "http://",
|
|
||||||
self.fhdhr.config.dict["origin"]["address"],
|
|
||||||
str(self.fhdhr.config.dict["origin"]["port"]),
|
|
||||||
))
|
|
||||||
|
|
||||||
initiate_req = self.fhdhr.web.session.get(initiate_url)
|
initiate_req = self.fhdhr.web.session.get(initiate_url)
|
||||||
initiate_dict = xmltodict.parse(initiate_req.content)
|
initiate_dict = xmltodict.parse(initiate_req.content)
|
||||||
@ -40,13 +42,8 @@ class OriginService():
|
|||||||
string = ':%s:%s' % (md5PIN, salt)
|
string = ':%s:%s' % (md5PIN, salt)
|
||||||
clientKey = hashlib.md5(string.encode('utf-8')).hexdigest()
|
clientKey = hashlib.md5(string.encode('utf-8')).hexdigest()
|
||||||
|
|
||||||
login_url = ('%s%s:%s/service?method=session.login&sid=%s&md5=%s' %
|
login_url = ('%s/service?method=session.login&sid=%s&md5=%s' %
|
||||||
("https://" if self.fhdhr.config.dict["origin"]["ssl"] else "http://",
|
(self.nextpvr_address, sid, clientKey))
|
||||||
self.fhdhr.config.dict["origin"]["address"],
|
|
||||||
str(self.fhdhr.config.dict["origin"]["port"]),
|
|
||||||
sid,
|
|
||||||
clientKey
|
|
||||||
))
|
|
||||||
login_req = self.fhdhr.web.session.get(login_url)
|
login_req = self.fhdhr.web.session.get(login_url)
|
||||||
login_dict = xmltodict.parse(login_req.content)
|
login_dict = xmltodict.parse(login_req.content)
|
||||||
|
|
||||||
@ -56,15 +53,3 @@ class OriginService():
|
|||||||
loginsuccess = sid
|
loginsuccess = sid
|
||||||
|
|
||||||
return loginsuccess
|
return loginsuccess
|
||||||
|
|
||||||
def get_status_dict(self):
|
|
||||||
nextpvr_address = ('%s%s:%s' %
|
|
||||||
("https://" if self.fhdhr.config.dict["origin"]["ssl"] else "http://",
|
|
||||||
self.fhdhr.config.dict["origin"]["address"],
|
|
||||||
str(self.fhdhr.config.dict["origin"]["port"]),
|
|
||||||
))
|
|
||||||
ret_status_dict = {
|
|
||||||
"Login": "Success",
|
|
||||||
"Address": nextpvr_address,
|
|
||||||
}
|
|
||||||
return ret_status_dict
|
|
||||||
|
|||||||
12
origin/origin_web/__init__.py
Normal file
12
origin/origin_web/__init__.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
from .origin_api import Origin_API
|
||||||
|
from .origin_html import Origin_HTML
|
||||||
|
|
||||||
|
|
||||||
|
class fHDHR_Origin_Web():
|
||||||
|
|
||||||
|
def __init__(self, fhdhr):
|
||||||
|
self.fhdhr = fhdhr
|
||||||
|
|
||||||
|
self.origin_api = Origin_API(fhdhr)
|
||||||
|
self.origin_html = Origin_HTML(fhdhr)
|
||||||
16
origin/origin_web/origin_api.py
Normal file
16
origin/origin_web/origin_api.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
|
||||||
|
class Origin_API():
|
||||||
|
endpoints = ["/api/origin"]
|
||||||
|
endpoint_name = "api_origin"
|
||||||
|
endpoint_methods = ["GET", "POST"]
|
||||||
|
|
||||||
|
def __init__(self, fhdhr):
|
||||||
|
self.fhdhr = fhdhr
|
||||||
|
|
||||||
|
def __call__(self, *args):
|
||||||
|
return self.get(*args)
|
||||||
|
|
||||||
|
def get(self, *args):
|
||||||
|
|
||||||
|
return "Success"
|
||||||
30
origin/origin_web/origin_html.py
Normal file
30
origin/origin_web/origin_html.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
from flask import request, render_template_string
|
||||||
|
import pathlib
|
||||||
|
from io import StringIO
|
||||||
|
|
||||||
|
|
||||||
|
class Origin_HTML():
|
||||||
|
endpoints = ["/origin", "/origin.html"]
|
||||||
|
endpoint_name = "page_origin_html"
|
||||||
|
|
||||||
|
def __init__(self, fhdhr):
|
||||||
|
self.fhdhr = fhdhr
|
||||||
|
|
||||||
|
self.template_file = pathlib.Path(self.fhdhr.config.internal["paths"]["origin_web"]).joinpath('origin.html')
|
||||||
|
self.template = StringIO()
|
||||||
|
self.template.write(open(self.template_file).read())
|
||||||
|
|
||||||
|
def __call__(self, *args):
|
||||||
|
return self.get(*args)
|
||||||
|
|
||||||
|
def get(self, *args):
|
||||||
|
|
||||||
|
if self.fhdhr.originwrapper.setup_success:
|
||||||
|
origin_status_dict = {
|
||||||
|
"Setup": "Success",
|
||||||
|
"Address": self.fhdhr.originwrapper.originservice.nextpvr_address,
|
||||||
|
"Total Channels": len(self.fhdhr.device.channels.list)
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
origin_status_dict = {"Setup": "Failed"}
|
||||||
|
return render_template_string(self.template.getvalue(), request=request, fhdhr=self.fhdhr, origin_status_dict=origin_status_dict, list=list)
|
||||||
Loading…
Reference in New Issue
Block a user