From 6baecab96098d61008d89b89bce119af9ed19575 Mon Sep 17 00:00:00 2001 From: deathbybandaid Date: Mon, 28 Sep 2020 08:40:29 -0400 Subject: [PATCH] test --- README.md | 25 +- data/cache/PLACEHOLDER | 0 data/garamond.ttf | Bin 0 -> 198604 bytes data/www/favicon.ico | Bin 0 -> 15406 bytes data/www/images/default-channel-thumb.png | Bin 0 -> 1413 bytes data/www/images/default-content-thumb.png | Bin 0 -> 1413 bytes epghandler/__init__.py | 252 +++++++++++++++ epghandler/zap2it.py | 203 ++++++++++++ fakehdhr/__init__.py | 362 ++++++++++++++++++++++ fhdhrconfig/__init__.py | 170 ++++++++++ main.py | 65 ++++ proxyservice/__init__.py | 292 +++++++++++++++++ requirements.txt | 4 + ssdpserver/__init__.py | 239 ++++++++++++++ 14 files changed, 1611 insertions(+), 1 deletion(-) create mode 100644 data/cache/PLACEHOLDER create mode 100644 data/garamond.ttf create mode 100644 data/www/favicon.ico create mode 100644 data/www/images/default-channel-thumb.png create mode 100644 data/www/images/default-content-thumb.png create mode 100644 epghandler/__init__.py create mode 100644 epghandler/zap2it.py create mode 100644 fakehdhr/__init__.py create mode 100644 fhdhrconfig/__init__.py create mode 100644 main.py create mode 100644 proxyservice/__init__.py create mode 100644 requirements.txt create mode 100644 ssdpserver/__init__.py diff --git a/README.md b/README.md index b428126..70c171c 100644 --- a/README.md +++ b/README.md @@ -1 +1,24 @@ -# FakeHDHR_NextPVR \ No newline at end of file +# FakeHDHR_NextPVR + +(based off of original code from + + * [tvhProxy by jkaberg](https://github.com/jkaberg/tvhProxy) + * [locast2plex by tgorgdotcom](https://github.com/tgorgdotcom/locast2plex) + * myself coding for locast2plex + + ) + +Until I have time to do the wiki thing for this project, instructions will be in this `README.md`. + +PRs welcome for: + +* Docker support + + +Vague Instructions (specific details intentionally excluded): + +* Install ffmpeg, and verify it is accessible in PATH. Otherwise, you may specify it's path in your configuration later. +* Install Python3 and Python3-pip. There will be no support for Python2. +* Download the zip of the `master` branch, or `git clone`. +* `pip3 install -r requirements.txt` +* Copy the included configuration example to a known path, and adjust as needed. The script will look in the current directory for `config.ini`, but this can be specified with the commandline argument `--config_file=` diff --git a/data/cache/PLACEHOLDER b/data/cache/PLACEHOLDER new file mode 100644 index 0000000..e69de29 diff --git a/data/garamond.ttf b/data/garamond.ttf new file mode 100644 index 0000000000000000000000000000000000000000..0a059a401c7a1c92c18213281690c3eae37e4745 GIT binary patch literal 198604 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 literal 0 HcmV?d00001 diff --git a/data/www/images/default-channel-thumb.png b/data/www/images/default-channel-thumb.png new file mode 100644 index 0000000000000000000000000000000000000000..b228b0c6682fcfeed64f4d4102c9adaccae91f4d GIT binary patch literal 1413 zcmeAS@N?(olHy`uVBq!ia0vp^Yk;_sgAGW=G6xy}DaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(eheoCO|{#S9F5M?jcysy3fA0|Tp+r;B4qMcmuF_r33>${hRnyKq_9t@mrz ztZ>to*;;k(S7E@yfOOYQ7aQx3m2LRT7;W&sOVLqy6UU;XVXwtq)Scu!SX~{pmndCv zIJ>p%`(C>O`|m|n0l#9t)E%7ux>%w0-J{2EzyG|tt0You&6@QYUN7H-r<6Q&U7OdR3YvU@;9hV&5H!M5$;=_t%Q`Bxxo+Xw1`4QNG0 zhv?lUbsp1!=Gay)o+f_5_f_4d#KhJ^hqzi>MY*`Ofl4*NCN12s!HL=uUfJ(gS6kan zS-kr1N*;Ud&GJ(h{<&2><)K+>hUUeuH^4R?eeLmKtx?UoGkM`{pOk;R4{A$H{oy&Y zSL1N$skJd7ZTV9c{;9vWf~Q_%^ZO}@zLKXFpEEsG&}_82UheDlSxJY%9$Bw^(E3!t zUZZL!$*QT5wc-!hQ-4Ivv|Y~gwJ^!}>-u-sr#|#d-R3V@7o3)_>HO0+?dkW>dcK6p zEjv6VPtEtQjWIaX)+)N5*LpF}cg@Yrr|N_L9}LXD@%dDakL0_syruWb)@vTVeCkbN z>W*7&wSkhS&PM(}t*f=!ALt=n<8?gFUd%ZW5x^jPRI8%#zLrnxuw3f54x=mg3(aLY z?}fBYpR({@a+dLat;5x)azZ5Kf~6854u7xgSlPejpK0`}|6F?iXPvtjp7!-_TlAFZ zn*nY8Qxcc=vpluE`9?T(+Y+9yb362o0bL1{BD7cgo(^J}jAPwt(m9-L};$ z>$|=>Z?&#fSuy|3znMm>_x}%{!UhcELv3g60@D0756hlfdqw(dZt9JfywU#!BkV$c zcN^_lV{!murij_;^C?~0`&E|h`E=TETk+HCy-&B^{v^0`&nNAk$EWm}we*#tiRDJ# z^!LlBh1a!3#r%AD{nM|#JD#mtZ6o(&x5(4f7GTQyp13)$%I=Nyse=7RQ{Hdiu#V^H z->X%kw(HKk`oHYrEkv9(8QocP=3Pjh``?-ipWZgg1+@KIYCe1A{Z$!plJ7#(wre^6 zT>aNOH6pO>lc(-=Ag|2h>*tEo>(}02evm^NoN_Bp(=s%_*fQ^BUb&|s zFX;PZP~Pke7M7JiWmv9QKS}R`>@DTF^G}|FI0l?;l@D$-K5nvf%eIO3G4eMeYpZ{m zEG>D|Dm+UHl3XrDMa90d5b~+DSgN^n=1)mq-ad{W`cvE+-dt#Oo)u*E>5U*br*F}V zUG_8oboObW*!QoNzP&GZX8LOC>gZ);t;t)H#k4NOzRSwWW|ijBli!vsJNCo*@vI=J kH_}(GK$6+SDgT(b&akZIznVG+SadRYy85}Sb4q9e0JS}npa1{> literal 0 HcmV?d00001 diff --git a/data/www/images/default-content-thumb.png b/data/www/images/default-content-thumb.png new file mode 100644 index 0000000000000000000000000000000000000000..b228b0c6682fcfeed64f4d4102c9adaccae91f4d GIT binary patch literal 1413 zcmeAS@N?(olHy`uVBq!ia0vp^Yk;_sgAGW=G6xy}DaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(eheoCO|{#S9F5M?jcysy3fA0|Tp+r;B4qMcmuF_r33>${hRnyKq_9t@mrz ztZ>to*;;k(S7E@yfOOYQ7aQx3m2LRT7;W&sOVLqy6UU;XVXwtq)Scu!SX~{pmndCv zIJ>p%`(C>O`|m|n0l#9t)E%7ux>%w0-J{2EzyG|tt0You&6@QYUN7H-r<6Q&U7OdR3YvU@;9hV&5H!M5$;=_t%Q`Bxxo+Xw1`4QNG0 zhv?lUbsp1!=Gay)o+f_5_f_4d#KhJ^hqzi>MY*`Ofl4*NCN12s!HL=uUfJ(gS6kan zS-kr1N*;Ud&GJ(h{<&2><)K+>hUUeuH^4R?eeLmKtx?UoGkM`{pOk;R4{A$H{oy&Y zSL1N$skJd7ZTV9c{;9vWf~Q_%^ZO}@zLKXFpEEsG&}_82UheDlSxJY%9$Bw^(E3!t zUZZL!$*QT5wc-!hQ-4Ivv|Y~gwJ^!}>-u-sr#|#d-R3V@7o3)_>HO0+?dkW>dcK6p zEjv6VPtEtQjWIaX)+)N5*LpF}cg@Yrr|N_L9}LXD@%dDakL0_syruWb)@vTVeCkbN z>W*7&wSkhS&PM(}t*f=!ALt=n<8?gFUd%ZW5x^jPRI8%#zLrnxuw3f54x=mg3(aLY z?}fBYpR({@a+dLat;5x)azZ5Kf~6854u7xgSlPejpK0`}|6F?iXPvtjp7!-_TlAFZ zn*nY8Qxcc=vpluE`9?T(+Y+9yb362o0bL1{BD7cgo(^J}jAPwt(m9-L};$ z>$|=>Z?&#fSuy|3znMm>_x}%{!UhcELv3g60@D0756hlfdqw(dZt9JfywU#!BkV$c zcN^_lV{!murij_;^C?~0`&E|h`E=TETk+HCy-&B^{v^0`&nNAk$EWm}we*#tiRDJ# z^!LlBh1a!3#r%AD{nM|#JD#mtZ6o(&x5(4f7GTQyp13)$%I=Nyse=7RQ{Hdiu#V^H z->X%kw(HKk`oHYrEkv9(8QocP=3Pjh``?-ipWZgg1+@KIYCe1A{Z$!plJ7#(wre^6 zT>aNOH6pO>lc(-=Ag|2h>*tEo>(}02evm^NoN_Bp(=s%_*fQ^BUb&|s zFX;PZP~Pke7M7JiWmv9QKS}R`>@DTF^G}|FI0l?;l@D$-K5nvf%eIO3G4eMeYpZ{m zEG>D|Dm+UHl3XrDMa90d5b~+DSgN^n=1)mq-ad{W`cvE+-dt#Oo)u*E>5U*br*F}V zUG_8oboObW*!QoNzP&GZX8LOC>gZ);t;t)H#k4NOzRSwWW|ijBli!vsJNCo*@vI=J kH_}(GK$6+SDgT(b&akZIznVG+SadRYy85}Sb4q9e0JS}npa1{> literal 0 HcmV?d00001 diff --git a/epghandler/__init__.py b/epghandler/__init__.py new file mode 100644 index 0000000..2aa5430 --- /dev/null +++ b/epghandler/__init__.py @@ -0,0 +1,252 @@ +import os +import sys +import time +import datetime +from io import BytesIO +import json +import xml.etree.ElementTree as ET + +from . import zap2it + + +def sub_el(parent, name, text=None, **kwargs): + el = ET.SubElement(parent, name, **kwargs) + if text: + el.text = text + return el + + +def clean_exit(): + sys.stderr.flush() + sys.stdout.flush() + os._exit(0) + + +class EPGhandler(): + + def __init__(self, config, serviceproxy): + self.config = config.config + self.serviceproxy = serviceproxy + self.zapepg = zap2it.ZapEPG(config) + + self.epg_cache = None + + self.empty_cache_dir = config.config["main"]["empty_cache"] + self.empty_cache_file = config.config["main"]["empty_cache_file"] + + def get_epg(self): + if self.config["fakehdhr"]["epg_method"] == "empty": + epgdict = self.epg_cache_open() + elif self.config["fakehdhr"]["epg_method"] == "proxy": + epgdict = self.serviceproxy.epg_cache_open() + elif self.config["fakehdhr"]["epg_method"] == "zap2it": + epgdict = self.zapepg.epg_cache_open() + return epgdict + + def epg_cache_open(self): + epg_cache = None + if os.path.isfile(self.empty_cache_file): + with open(self.empty_cache_file, 'r') as epgfile: + epg_cache = json.load(epgfile) + return epg_cache + + def get_xmltv(self, base_url): + epgdict = self.get_epg() + if not epgdict: + return self.dummyxml() + + epg_method = self.config["fakehdhr"]["epg_method"] + + out = ET.Element('tv') + out.set('source-info-url', 'NextPVR') + out.set('source-info-name', 'NextPVR') + out.set('generator-info-name', 'FAKEHDHR') + out.set('generator-info-url', 'FAKEHDHR/FakeHDHR_NextPVR') + + for channel in list(epgdict.keys()): + c_out = sub_el(out, 'channel', id=epgdict[channel]['id']) + sub_el(c_out, 'display-name', + text='%s %s' % (epgdict[channel]['number'], epgdict[channel]['callsign'])) + sub_el(c_out, 'display-name', text=epgdict[channel]['number']) + sub_el(c_out, 'display-name', text=epgdict[channel]['callsign']) + + if epg_method == "empty": + sub_el(c_out, 'icon', src=("http://" + str(base_url) + str(epgdict[channel]['thumbnail']))) + elif epg_method == "proxy": + sub_el(c_out, 'icon', src=("http://" + str(base_url) + str(epgdict[channel]['thumbnail']))) + elif epg_method == "zap2it": + sub_el(c_out, 'icon', src=(str(epgdict[channel]['thumbnail']))) + else: + sub_el(c_out, 'icon', src=(str(epgdict[channel]['thumbnail']))) + + for channel in list(epgdict.keys()): + channel_listing = epgdict[channel]['listing'] + + for program in channel_listing: + + prog_out = sub_el(out, 'programme', + start=program['time_start'], + stop=program['time_end'], + channel=epgdict[channel]["id"]) + + if program['title']: + sub_el(prog_out, 'title', lang='en', text=program['title']) + + if 'movie' in program['genres'] and program['releaseyear']: + sub_el(prog_out, 'sub-title', lang='en', text='Movie: ' + program['releaseyear']) + elif program['episodetitle']: + sub_el(prog_out, 'sub-title', lang='en', text=program['episodetitle']) + + sub_el(prog_out, 'length', units='minutes', text=str(int(program['duration_minutes']))) + + for f in program['genres']: + sub_el(prog_out, 'category', lang='en', text=f) + sub_el(prog_out, 'genre', lang='en', text=f) + + if program["thumbnail"] is not None: + if epg_method == "empty": + sub_el(prog_out, 'icon', src=("http://" + str(base_url) + str(program['thumbnail']))) + elif epg_method == "proxy": + sub_el(prog_out, 'icon', src=("http://" + str(base_url) + str(program['thumbnail']))) + elif epg_method == "zap2it": + sub_el(prog_out, 'icon', src=(str(program['thumbnail']))) + else: + sub_el(prog_out, 'icon', src=(str(program['thumbnail']))) + + if program['rating']: + r = ET.SubElement(prog_out, 'rating') + sub_el(r, 'value', text=program['rating']) + + if 'seasonnumber' in list(program.keys()) and 'episodenumber' in list(program.keys()): + if program['seasonnumber'] and program['episodenumber']: + s_ = int(program['seasonnumber'], 10) + e_ = int(program['episodenumber'], 10) + sub_el(prog_out, 'episode-num', system='common', + text='S%02dE%02d' % (s_, e_)) + sub_el(prog_out, 'episode-num', system='xmltv_ns', + text='%d.%d.' % (int(s_)-1, int(e_)-1)) + sub_el(prog_out, 'episode-num', system='SxxExx">S', + text='S%02dE%02d' % (s_, e_)) + + # if 'New' in event['flag'] and 'live' not in event['flag']: + # sub_el(prog_out, 'new') + + fakefile = BytesIO() + fakefile.write(b'\n') + fakefile.write(ET.tostring(out, encoding='UTF-8')) + return fakefile.getvalue() + + def dummyxml(self): + out = ET.Element('tv') + out.set('source-info-url', 'NextPVR') + out.set('source-info-name', 'NextPVR') + out.set('generator-info-name', 'FAKEHDHR') + out.set('generator-info-url', 'FAKEHDHR/FakeHDHR_NextPVR') + + fakefile = BytesIO() + fakefile.write(b'\n') + fakefile.write(ET.tostring(out, encoding='UTF-8')) + return fakefile.getvalue() + + def update_epg(self): + print('Updating Empty EPG cache file.') + + programguide = {} + + timestamps = [] + todaydate = datetime.date.today() + for x in range(0, 6): + xdate = todaydate + datetime.timedelta(days=x) + xtdate = xdate + datetime.timedelta(days=1) + + for hour in range(0, 24): + time_start = datetime.datetime.combine(xdate, datetime.time(hour, 0)) + if hour + 1 < 24: + time_end = datetime.datetime.combine(xdate, datetime.time(hour + 1, 0)) + else: + time_end = datetime.datetime.combine(xtdate, datetime.time(0, 0)) + timestampdict = { + "time_start": str(time_start.strftime('%Y%m%d%H%M%S')) + " +0000", + "time_end": str(time_end.strftime('%Y%m%d%H%M%S')) + " +0000", + } + timestamps.append(timestampdict) + + for c in self.serviceproxy.get_channels(): + if str(c["formatted-number"]) not in list(programguide.keys()): + programguide[str(c["formatted-number"])] = {} + + channel_thumb_path = ("/images?source=empty&type=channel&id=%s" % (str(c['formatted-number']))) + programguide[str(c["formatted-number"])]["thumbnail"] = channel_thumb_path + + if "name" not in list(programguide[str(c["formatted-number"])].keys()): + programguide[str(c["formatted-number"])]["name"] = c["name"] + + if "callsign" not in list(programguide[str(c["formatted-number"])].keys()): + programguide[str(c["formatted-number"])]["callsign"] = c["name"] + + if "id" not in list(programguide[str(c["formatted-number"])].keys()): + programguide[str(c["formatted-number"])]["id"] = c["id"] + + if "number" not in list(programguide[str(c["formatted-number"])].keys()): + programguide[str(c["formatted-number"])]["number"] = c["formatted-number"] + + if "listing" not in list(programguide[str(c["formatted-number"])].keys()): + programguide[str(c["formatted-number"])]["listing"] = [] + + for timestamp in timestamps: + clean_prog_dict = {} + + clean_prog_dict["time_start"] = timestamp['time_start'] + clean_prog_dict["time_end"] = timestamp['time_end'] + clean_prog_dict["duration_minutes"] = 60.0 + + content_thumb = ("/images?source=empty&type=content&id=%s" % (str(c['formatted-number']))) + clean_prog_dict["thumbnail"] = content_thumb + + clean_prog_dict["title"] = "Unavailable" + + clean_prog_dict["genres"] = [] + + clean_prog_dict["sub-title"] = "Unavailable" + + clean_prog_dict['releaseyear'] = "" + clean_prog_dict["episodetitle"] = "Unavailable" + + clean_prog_dict["description"] = "Unavailable" + + clean_prog_dict['rating'] = "N/A" + + programguide[str(c["formatted-number"])]["listing"].append(clean_prog_dict) + + self.epg_cache = programguide + with open(self.empty_cache_file, 'w') as epgfile: + epgfile.write(json.dumps(programguide, indent=4)) + print('Wrote updated Empty EPG cache file.') + return programguide + + def update(self): + if self.config["fakehdhr"]["epg_method"] == "empty": + self.update_epg() + elif self.config["fakehdhr"]["epg_method"] == "proxy": + self.serviceproxy.update_epg() + elif self.config["fakehdhr"]["epg_method"] == "zap2it": + self.zapepg.update_epg() + + +def epgServerProcess(config, epghandling): + + if config.config["fakehdhr"]["epg_method"] == "empty": + sleeptime = config.config["main"]["empty_epg_update_frequency"] + elif config.config["fakehdhr"]["epg_method"] == "proxy": + sleeptime = config.config["nextpvr"]["epg_update_frequency"] + elif config.config["fakehdhr"]["epg_method"] == "zap2it": + sleeptime = config.config["zap2xml"]["epg_update_frequency"] + + try: + + while True: + epghandling.update() + time.sleep(sleeptime) + + except KeyboardInterrupt: + clean_exit() diff --git a/epghandler/zap2it.py b/epghandler/zap2it.py new file mode 100644 index 0000000..f3fa88f --- /dev/null +++ b/epghandler/zap2it.py @@ -0,0 +1,203 @@ +import os +import json +import time +import datetime +import urllib.error +import urllib.parse +import urllib.request + + +def xmltimestamp_zap(inputtime): + xmltime = inputtime.replace('Z', '+00:00') + xmltime = datetime.datetime.fromisoformat(xmltime) + xmltime = xmltime.strftime('%Y%m%d%H%M%S %z') + return xmltime + + +def duration_nextpvr_minutes(starttime, endtime): + return ((int(endtime) - int(starttime))/1000/60) + + +class ZapEPG(): + + def __init__(self, config): + + self.config = config.config + self.postalcode = config.config["zap2xml"]["postalcode"] + if not self.postalcode: + self.postalcode = self.get_location() + + self.epg_cache = None + self.cache_dir = config.config["main"]["zap_web_cache"] + self.epg_cache_file = config.config["zap2xml"]["epg_cache"] + self.epg_cache = self.epg_cache_open() + + def get_location(self): + url = 'http://ipinfo.io/json' + response = urllib.request.urlopen(url) + data = json.load(response) + return data["postal"] + + def epg_cache_open(self): + epg_cache = None + if os.path.isfile(self.epg_cache_file): + with open(self.epg_cache_file, 'r') as epgfile: + epg_cache = json.load(epgfile) + return epg_cache + + def get_cached(self, cache_key, delay, url): + cache_path = self.cache_dir.joinpath(cache_key) + if cache_path.is_file(): + print('FROM CACHE:', str(cache_path)) + with open(cache_path, 'rb') as f: + return f.read() + else: + print('Fetching: ', url) + try: + resp = urllib.request.urlopen(url) + result = resp.read() + except urllib.error.HTTPError as e: + if e.code == 400: + print('Got a 400 error! Ignoring it.') + result = ( + b'{' + b'"note": "Got a 400 error at this time, skipping.",' + b'"channels": []' + b'}') + else: + raise + with open(cache_path, 'wb') as f: + f.write(result) + return result + + def remove_stale_cache(self, todaydate): + for p in self.cache_dir.glob('*'): + try: + cachedate = datetime.datetime.strptime(str(p.name), "%Y-%m-%d") + todaysdate = datetime.datetime.strptime(str(todaydate), "%Y-%m-%d") + if cachedate >= todaysdate: + continue + except Exception as e: + print(e) + pass + print('Removing stale cache file:', p.name) + p.unlink() + + def update_epg(self): + print('Updating Zap2it EPG cache file.') + programguide = {} + + # Start time parameter is now rounded down to nearest `zap_timespan`, in s. + zap_time = time.mktime(time.localtime()) + zap_time_window = int(self.config["zap2xml"]["timespan"]) * 3600 + zap_time = int(zap_time - (zap_time % zap_time_window)) + + # Fetch data in `zap_timespan` chunks. + for i in range(int(7 * 24 / int(self.config["zap2xml"]["timespan"]))): + i_time = zap_time + (i * zap_time_window) + + parameters = { + 'aid': self.config["zap2xml"]['affiliate_id'], + 'country': self.config["zap2xml"]['country'], + 'device': self.config["zap2xml"]['device'], + 'headendId': self.config["zap2xml"]['headendid'], + 'isoverride': "true", + 'languagecode': self.config["zap2xml"]['languagecode'], + 'pref': 'm,p', + 'timespan': self.config["zap2xml"]['timespan'], + 'timezone': self.config["zap2xml"]['timezone'], + 'userId': self.config["zap2xml"]['userid'], + 'postalCode': self.config["zap2xml"]['postalcode'], + 'lineupId': '%s-%s-DEFAULT' % (self.config["zap2xml"]['country'], self.config["zap2xml"]['device']), + 'time': i_time, + 'Activity_ID': 1, + 'FromPage': "TV%20Guide", + } + + url = 'https://tvlistings.zap2it.com/api/grid?' + url += urllib.parse.urlencode(parameters) + + result = self.get_cached(str(i_time), self.config["zap2xml"]['delay'], url) + d = json.loads(result) + + for c in d['channels']: + + if str(c['channelNo']) not in list(programguide.keys()): + programguide[str(c['channelNo'])] = {} + + channel_thumb = str(c['thumbnail']).replace("//", "https://").split("?")[0] + programguide[str(c["channelNo"])]["thumbnail"] = channel_thumb + + if "name" not in list(programguide[str(c["channelNo"])].keys()): + programguide[str(c["channelNo"])]["name"] = c["callSign"] + + if "callsign" not in list(programguide[str(c["channelNo"])].keys()): + programguide[str(c["channelNo"])]["callsign"] = c["callSign"] + + if "id" not in list(programguide[str(c["channelNo"])].keys()): + programguide[str(c["channelNo"])]["id"] = c["channelId"] + + if "number" not in list(programguide[str(c["channelNo"])].keys()): + programguide[str(c["channelNo"])]["number"] = c["channelNo"] + + if "listing" not in list(programguide[str(c["channelNo"])].keys()): + programguide[str(c["channelNo"])]["listing"] = [] + + for event in c['events']: + clean_prog_dict = {} + + prog_in = event['program'] + + clean_prog_dict["time_start"] = xmltimestamp_zap(event['startTime']) + clean_prog_dict["time_end"] = xmltimestamp_zap(event['endTime']) + clean_prog_dict["duration_minutes"] = event['duration'] + + content_thumb = str("https://zap2it.tmsimg.com/assets/" + str(event['thumbnail']) + ".jpg") + clean_prog_dict["thumbnail"] = content_thumb + + if 'title' not in list(prog_in.keys()): + prog_in["title"] = "Unavailable" + elif not prog_in["title"]: + prog_in["title"] = "Unavailable" + clean_prog_dict["title"] = prog_in["title"] + + clean_prog_dict["genres"] = [] + if 'filter' in list(event.keys()): + for f in event['filter']: + clean_prog_dict["genres"].append(f.replace('filter-', '')) + + if 'filter-movie' in event['filter'] and prog_in['releaseYear']: + clean_prog_dict["sub-title"] = 'Movie: ' + prog_in['releaseYear'] + elif prog_in['episodeTitle']: + clean_prog_dict["sub-title"] = prog_in['episodeTitle'] + else: + clean_prog_dict["sub-title"] = "Unavailable" + + clean_prog_dict['releaseyear'] = prog_in['releaseYear'] + + if prog_in['shortDesc'] is None: + prog_in['shortDesc'] = "Unavailable" + clean_prog_dict["description"] = prog_in['shortDesc'] + + if 'rating' not in list(event.keys()): + event['rating'] = "N/A" + clean_prog_dict['rating'] = event['rating'] + + if 'season' in list(prog_in.keys()) and 'episode' in list(prog_in.keys()): + clean_prog_dict["seasonnumber"] = prog_in['season'] + clean_prog_dict["episodenumber"] = prog_in['episode'] + clean_prog_dict["episodetitle"] = clean_prog_dict["sub-title"] + else: + if "movie" not in clean_prog_dict["genres"]: + clean_prog_dict["episodetitle"] = clean_prog_dict["sub-title"] + + if 'New' in event['flag'] and 'live' not in event['flag']: + clean_prog_dict["isnew"] = True + + programguide[str(c["channelNo"])]["listing"].append(clean_prog_dict) + + self.epg_cache = programguide + with open(self.epg_cache_file, 'w') as epgfile: + epgfile.write(json.dumps(programguide, indent=4)) + print('Wrote updated Zap2it EPG cache file.') + return programguide diff --git a/fakehdhr/__init__.py b/fakehdhr/__init__.py new file mode 100644 index 0000000..e62d7a2 --- /dev/null +++ b/fakehdhr/__init__.py @@ -0,0 +1,362 @@ +from gevent.pywsgi import WSGIServer +from flask import (Flask, send_from_directory, request, Response, + abort, stream_with_context) +from io import BytesIO +import xml.etree.ElementTree as ET +import json +import time +import requests +import subprocess +import errno +import PIL.Image +import PIL.ImageDraw +import PIL.ImageFont + + +def sub_el(parent, name, text=None, **kwargs): + el = ET.SubElement(parent, name, **kwargs) + if text: + el.text = text + return el + + +def getSize(txt, font): + testImg = PIL.Image.new('RGB', (1, 1)) + testDraw = PIL.ImageDraw.Draw(testImg) + return testDraw.textsize(txt, font) + + +class HDHR_Hub(): + config = None + serviceproxy = None + epghandling = None + station_scan = False + station_list = [] + + def __init__(self): + self.station_scan = False + + def get_xmltv(self, base_url): + return self.epghandling.get_xmltv(base_url) + + def get_image(self, req_args): + imageid = req_args["id"] + + if req_args["source"] == "proxy": + if req_args["type"] == "channel": + imageUri = self.serviceproxy.get_channel_thumbnail(imageid) + elif req_args["type"] == "content": + imageUri = self.serviceproxy.get_content_thumbnail(imageid) + req = requests.get(imageUri) + return req.content + + elif req_args["source"] == "empty": + if req_args["type"] == "channel": + width = 360 + height = 270 + text = req_args["id"] + fontsize = 72 + elif req_args["type"] == "content": + width = 1080 + height = 1440 + fontsize = 100 + text = req_args["id"] + + colorBackground = "#228822" + colorText = "#717D7E" + colorOutline = "#717D7E" + fontname = str(self.config["fakehdhr"]["font"]) + + font = PIL.ImageFont.truetype(fontname, fontsize) + text_width, text_height = getSize(text, font) + img = PIL.Image.new('RGBA', (width+4, height+4), colorBackground) + d = PIL.ImageDraw.Draw(img) + d.text(((width-text_width)/2, (height-text_height)/2), text, fill=colorText, font=font) + d.rectangle((0, 0, width+3, height+3), outline=colorOutline) + + s = BytesIO() + img.save(s, 'png') + return s.getvalue() + + def get_xmldiscover(self, base_url): + out = ET.Element('root') + out.set('xmlns', "urn:schemas-upnp-org:device-1-0") + + sub_el(out, 'URLBase', "http://" + base_url) + + specVersion_out = sub_el(out, 'specVersion') + sub_el(specVersion_out, 'major', "1") + sub_el(specVersion_out, 'minor', "0") + + device_out = sub_el(out, 'device') + sub_el(device_out, 'deviceType', "urn:schemas-upnp-org:device:MediaServer:1") + sub_el(device_out, 'friendlyName', self.config["fakehdhr"]["friendlyname"]) + sub_el(device_out, 'manufacturer', "Silicondust") + sub_el(device_out, 'modelName', self.config["dev"]["reporting_model"]) + sub_el(device_out, 'modelNumber', self.config["dev"]["reporting_model"]) + sub_el(device_out, 'serialNumber') + sub_el(device_out, 'UDN', "uuid:" + self.config["main"]["uuid"]) + + fakefile = BytesIO() + fakefile.write(b'\n') + fakefile.write(ET.tostring(out, encoding='UTF-8')) + return fakefile.getvalue() + + def get_discover_json(self, base_url): + jsondiscover = { + "FriendlyName": self.config["fakehdhr"]["friendlyname"], + "Manufacturer": "Silicondust", + "ModelNumber": self.config["dev"]["reporting_model"], + "FirmwareName": self.config["dev"]["reporting_firmware_name"], + "TunerCount": self.config["fakehdhr"]["tuner_count"], + "FirmwareVersion": self.config["dev"]["reporting_firmware_ver"], + "DeviceID": self.config["main"]["uuid"], + "DeviceAuth": "nextpvrproxy", + "BaseURL": "http://" + base_url, + "LineupURL": "http://" + base_url + "/lineup.json" + } + return jsondiscover + + def get_lineup_status(self): + if self.station_scan: + channel_count = self.serviceproxy.get_station_total() + jsonlineup = { + "ScanInProgress": "true", + "Progress": 99, + "Found": channel_count + } + else: + jsonlineup = { + "ScanInProgress": "false", + "ScanPossible": "true", + "Source": self.config["dev"]["reporting_tuner_type"], + "SourceList": [self.config["dev"]["reporting_tuner_type"]], + } + return jsonlineup + + def get_lineup_xml(self, base_url): + out = ET.Element('Lineup') + station_list = self.serviceproxy.get_station_list(base_url) + for station_item in station_list: + program_out = sub_el(out, 'Program') + sub_el(program_out, 'GuideNumber', station_item['GuideNumber']) + sub_el(program_out, 'GuideName', station_item['GuideName']) + sub_el(program_out, 'URL', station_item['URL']) + + fakefile = BytesIO() + fakefile.write(b'\n') + fakefile.write(ET.tostring(out, encoding='UTF-8')) + return fakefile.getvalue() + + def get_debug(self, base_url): + debugjson = { + "base_url": base_url, + } + return debugjson + + def get_html_error(self, message): + htmlerror = """ + + +

{}

+ + """ + return htmlerror.format(message) + + def station_scan_change(self, enablement): + self.station_scan = enablement + + +hdhr = HDHR_Hub() + + +class HDHR_HTTP_Server(): + app = Flask(__name__,) + + @app.route('/') + def root_path(): + return hdhr.config["fakehdhr"]["friendlyname"] + + @app.route('/favicon.ico', methods=['GET']) + def favicon(): + return send_from_directory(hdhr.config["main"]["www_dir"], + 'favicon.ico', + mimetype='image/vnd.microsoft.icon') + + @app.route('/device.xml', methods=['GET']) + def device_xml(): + base_url = request.headers["host"] + devicexml = hdhr.get_xmldiscover(base_url) + return Response(status=200, + response=devicexml, + mimetype='application/xml') + + @app.route('/discover.json', methods=['GET']) + def discover_json(): + base_url = request.headers["host"] + jsondiscover = hdhr.get_discover_json(base_url) + return Response(status=200, + response=json.dumps(jsondiscover, indent=4), + mimetype='application/json') + + @app.route('/lineup_status.json', methods=['GET']) + def lineup_status_json(): + linup_status_json = hdhr.get_lineup_status() + return Response(status=200, + response=json.dumps(linup_status_json, indent=4), + mimetype='application/json') + + @app.route('/lineup.xml', methods=['GET']) + def lineup_xml(): + base_url = request.headers["host"] + lineupxml = hdhr.get_lineup_xml(base_url) + return Response(status=200, + response=lineupxml, + mimetype='application/xml') + + @app.route('/lineup.json', methods=['GET']) + def lineup_json(): + base_url = request.headers["host"] + station_list = hdhr.serviceproxy.get_station_list(base_url) + return Response(status=200, + response=json.dumps(station_list, indent=4), + mimetype='application/json') + + @app.route('/xmltv.xml', methods=['GET']) + def xmltv_xml(): + base_url = request.headers["host"] + xmltv = hdhr.get_xmltv(base_url) + return Response(status=200, + response=xmltv, + mimetype='application/xml') + + @app.route('/debug.json', methods=['GET']) + def debug_json(): + base_url = request.headers["host"] + debugreport = hdhr.get_debug(base_url) + return Response(status=200, + response=json.dumps(debugreport, indent=4), + mimetype='application/json') + + @app.route('/images', methods=['GET']) + def images_nothing(): + if ('source' not in list(request.args.keys()) or 'id' not in list(request.args.keys()) or 'type' not in list(request.args.keys())): + abort(404) + + image = hdhr.get_image(request.args) + return Response(image, content_type='image/png', direct_passthrough=True) + + @app.route('/watch', methods=['GET']) + def watch_nothing(): + if 'method' in list(request.args.keys()): + if 'channel' in list(request.args.keys()): + + station_list = hdhr.serviceproxy.get_channel_streams() + channelUri = station_list[str(request.args["channel"])] + if not channelUri: + abort(404) + + if request.args["method"] == "direct": + duration = request.args.get('duration', default=0, type=int) + + if not duration == 0: + duration += time.time() + + req = requests.get(channelUri, stream=True) + + def generate(): + yield '' + for chunk in req.iter_content(chunk_size=hdhr.config["direct_stream"]['chunksize']): + if not duration == 0 and not time.time() < duration: + req.close() + break + yield chunk + + return Response(generate(), content_type=req.headers['content-type'], direct_passthrough=True) + + if request.args["method"] == "ffmpeg": + + ffmpeg_command = [hdhr.config["ffmpeg"]["ffmpeg_path"], + "-i", channelUri, + "-c", "copy", + "-f", "mpegts", + "-nostats", "-hide_banner", + "-loglevel", "warning", + "pipe:stdout" + ] + ffmpeg_proc = subprocess.Popen(ffmpeg_command, stdout=subprocess.PIPE) + + def generate(): + + videoData = ffmpeg_proc.stdout.read(int(hdhr.config["ffmpeg"]["bytes_per_read"])) + + while True: + if not videoData: + break + else: + # from https://stackoverflow.com/questions/9932332 + try: + yield videoData + time.sleep(0.1) + except IOError as e: + # Check we hit a broken pipe when trying to write back to the client + if e.errno == errno.EPIPE: + # Send SIGTERM to shutdown ffmpeg + ffmpeg_proc.terminate() + # ffmpeg writes a bit of data out to stderr after it terminates, + # need to read any hanging data to prevent a zombie process. + ffmpeg_proc.communicate() + break + else: + raise + + videoData = ffmpeg_proc.stdout.read(int(hdhr.config["ffmpeg"]["bytes_per_read"])) + + ffmpeg_proc.terminate() + try: + ffmpeg_proc.communicate() + except ValueError: + print("Connection Closed") + + return Response(stream_with_context(generate()), mimetype="audio/mpeg") + abort(404) + + @app.route('/lineup.post', methods=['POST']) + def lineup_post(): + if 'scan' in list(request.args.keys()): + if request.args['scan'] == 'start': + hdhr.station_scan_change(True) + hdhr.station_list = [] + hdhr.station_scan_change(False) + return Response(status=200, mimetype='text/html') + + elif request.args['scan'] == 'abort': + return Response(status=200, mimetype='text/html') + + else: + print("Unknown scan command " + request.args['scan']) + currenthtmlerror = hdhr.get_html_error("501 - " + request.args['scan'] + " is not a valid scan command") + return Response(status=200, response=currenthtmlerror, mimetype='text/html') + + else: + currenthtmlerror = hdhr.get_html_error("501 - not a valid command") + return Response(status=200, response=currenthtmlerror, mimetype='text/html') + + def __init__(self, config): + self.config = config.config + + def run(self): + http = WSGIServer(( + self.config["fakehdhr"]["address"], + int(self.config["fakehdhr"]["port"]) + ), self.app.wsgi_app) + http.serve_forever() + + +def interface_start(config, serviceproxy, epghandling): + hdhr.config = config.config + hdhr.station_scan = False + hdhr.serviceproxy = serviceproxy + hdhr.epghandling = epghandling + fakhdhrserver = HDHR_HTTP_Server(config) + fakhdhrserver.run() diff --git a/fhdhrconfig/__init__.py b/fhdhrconfig/__init__.py new file mode 100644 index 0000000..01e3401 --- /dev/null +++ b/fhdhrconfig/__init__.py @@ -0,0 +1,170 @@ +import os +import sys +import random +import configparser +import pathlib + + +def clean_exit(): + sys.stderr.flush() + sys.stdout.flush() + os._exit(0) + + +class HDHRConfig(): + + config_file = None + config_handler = configparser.ConfigParser() + script_dir = None + + config = { + "main": { + 'uuid': None, + "cache_dir": None, + "empty_epg_update_frequency": 43200, + }, + "nextpvr": { + "address": "localhost", + "port": 8866, + "ssl": False, + "pin": None, + "weight": 300, # subscription priority + "sidfile": None, + "epg_update_frequency": 43200, + }, + "fakehdhr": { + "address": "0.0.0.0", + "port": 5004, + "discovery_address": "0.0.0.0", + "tuner_count": 4, # number of tuners in tvh + "concurrent_listeners": 10, + "friendlyname": "fHDHR-NextPVR", + "stream_type": "direct", + "epg_method": "proxy", + "font": None, + }, + "zap2xml": { + "delay": 5, + "postalcode": None, + "affiliate_id": 'gapzap', + "country": 'USA', + "device": '-', + "headendid": "lineupId", + "isoverride": True, + "languagecode": 'en', + "pref": "", + "timespan": 6, + "timezone": "", + "userid": "-", + "epg_update_frequency": 43200, + }, + "ffmpeg": { + 'ffmpeg_path': "ffmpeg", + 'bytes_per_read': '1152000', + "font": None, + }, + "direct_stream": { + 'chunksize': 1024*1024 # usually you don't need to edit this + }, + "dev": { + 'reporting_model': 'HDHR4-2DT', + 'reporting_firmware_name': 'hdhomerun4_dvbt', + 'reporting_firmware_ver': '20150826', + 'reporting_tuner_type': "Antenna", + } + } + + def __init__(self, script_dir, args): + self.get_config_path(script_dir, args) + self.import_config() + self.config_adjustments(script_dir) + + def get_config_path(self, script_dir, args): + if args.cfg: + self.config_file = pathlib.Path(str(args.cfg)) + if not self.config_file or not os.path.exists(self.config_file): + print("Config file missing, Exiting...") + clean_exit() + print("Loading Configuration File: " + str(self.config_file)) + + def import_config(self): + self.config_handler.read(self.config_file) + for each_section in self.config_handler.sections(): + if each_section not in list(self.config.keys()): + self.config[each_section] = {} + for (each_key, each_val) in self.config_handler.items(each_section): + self.config[each_section.lower()][each_key.lower()] = each_val + + def write(self, section, key, value): + self.config[section][key] = value + self.config_handler.set(section, key, value) + + with open(self.config_file, 'w') as config_file: + self.config_handler.write(config_file) + + def config_adjustments(self, script_dir): + + self.config["main"]["script_dir"] = script_dir + + data_dir = pathlib.Path(script_dir).joinpath('data') + self.config["main"]["data_dir"] = data_dir + + self.config["fakehdhr"]["font"] = pathlib.Path(data_dir).joinpath('garamond.ttf') + + if not self.config["main"]["cache_dir"]: + self.config["main"]["cache_dir"] = pathlib.Path(data_dir).joinpath('cache') + else: + self.config["main"]["cache_dir"] = pathlib.Path(self.config["main"]["cache_dir"]) + if not self.config["main"]["cache_dir"].is_dir(): + print("Invalid Cache Directory. Exiting...") + clean_exit() + cache_dir = self.config["main"]["cache_dir"] + + if not self.config["nextpvr"]["pin"]: + print("NextPVR Login Credentials Missing. Exiting...") + clean_exit() + + empty_cache = pathlib.Path(cache_dir).joinpath('empty_cache') + self.config["main"]["empty_cache"] = empty_cache + if not empty_cache.is_dir(): + empty_cache.mkdir() + self.config["main"]["empty_cache_file"] = pathlib.Path(empty_cache).joinpath('epg.json') + + nextpvr_cache = pathlib.Path(cache_dir).joinpath('nextpvr') + self.config["main"]["nextpvr_cache"] = nextpvr_cache + if not nextpvr_cache.is_dir(): + nextpvr_cache.mkdir() + self.config["nextpvr"]["sidfile"] = pathlib.Path(nextpvr_cache).joinpath('sid.txt') + self.config["nextpvr"]["epg_cache"] = pathlib.Path(nextpvr_cache).joinpath('epg.json') + + zap_cache = pathlib.Path(cache_dir).joinpath('zap2it') + self.config["main"]["zap_cache"] = zap_cache + if not zap_cache.is_dir(): + zap_cache.mkdir() + self.config["zap2xml"]["epg_cache"] = pathlib.Path(zap_cache).joinpath('epg.json') + zap_web_cache = pathlib.Path(zap_cache).joinpath('zap_web_cache') + self.config["main"]["zap_web_cache"] = zap_web_cache + if not zap_web_cache.is_dir(): + zap_web_cache.mkdir() + + www_dir = pathlib.Path(data_dir).joinpath('www') + self.config["main"]["www_dir"] = www_dir + self.config["main"]["favicon"] = pathlib.Path(www_dir).joinpath('favicon.ico') + + www_image_dir = pathlib.Path(www_dir).joinpath('images') + self.config["main"]["www_image_dir"] = www_image_dir + self.config["main"]["image_def_channel"] = pathlib.Path(www_image_dir).joinpath("default-channel-thumb.png") + self.config["main"]["image_def_content"] = pathlib.Path(www_image_dir).joinpath("default-content-thumb.png") + + # generate UUID here for when we are not using docker + if self.config["main"]["uuid"] is None: + print("No UUID found. Generating one now...") + # from https://pynative.com/python-generate-random-string/ + # create a string that wouldn't be a real device uuid for + self.config["main"]["uuid"] = ''.join(random.choice("hijklmnopqrstuvwxyz") for i in range(8)) + self.write('main', 'uuid', self.config["main"]["uuid"]) + print("UUID set to: " + self.config["main"]["uuid"] + "...") + + print("Server is set to run on " + + str(self.config["fakehdhr"]["address"]) + ":" + + str(self.config["fakehdhr"]["port"])) diff --git a/main.py b/main.py new file mode 100644 index 0000000..d09b739 --- /dev/null +++ b/main.py @@ -0,0 +1,65 @@ +import os +import sys +import pathlib +import argparse +from multiprocessing import Process + +import fhdhrconfig +import proxyservice +import fakehdhr +import epghandler +import ssdpserver + +if sys.version_info.major == 2 or sys.version_info < (3, 3): + print('Error: FakeHDHR requires python 3.3+.') + sys.exit(1) + + +def get_args(): + parser = argparse.ArgumentParser(description='FakeHDHR.', epilog='') + parser.add_argument('--config_file', dest='cfg', type=str, default=None, help='') + return parser.parse_args() + + +def clean_exit(): + sys.stderr.flush() + sys.stdout.flush() + os._exit(0) + + +if __name__ == '__main__': + + # Gather args + args = get_args() + + # set to directory of script + script_dir = pathlib.Path(os.path.dirname(os.path.abspath(__file__))) + + # Open Configuration File + print("Opening and Verifying Configuration File.") + config = fhdhrconfig.HDHRConfig(script_dir, args) + + # Open proxyservice + serviceproxy = proxyservice.proxyserviceFetcher(config) + + # Open EPG Handler + epghandling = epghandler.EPGhandler(config, serviceproxy) + + try: + + print("Starting EPG thread...") + epgServer = Process(target=epghandler.epgServerProcess, args=(config, epghandling)) + epgServer.start() + + print("Starting fHDHR Interface") + fhdhrServer = Process(target=fakehdhr.interface_start, args=(config, serviceproxy, epghandling)) + fhdhrServer.start() + + print("Starting SSDP server...") + ssdpServer = Process(target=ssdpserver.ssdpServerProcess, args=(config,)) + ssdpServer.daemon = True + ssdpServer.start() + + except KeyboardInterrupt: + print('^C received, shutting down the server') + clean_exit() diff --git a/proxyservice/__init__.py b/proxyservice/__init__.py new file mode 100644 index 0000000..af52498 --- /dev/null +++ b/proxyservice/__init__.py @@ -0,0 +1,292 @@ +import os +import xmltodict +import json +import hashlib +import datetime +import urllib.error +import urllib.parse +import urllib.request + + +class NextPVR_Auth(): + config = { + 'npvrURL': '', + 'npvrSID': '', + 'npvrPIN': '', + } + sidfile = None + + def __init__(self, config): + self.sidfile = config.config["nextpvr"]["sidfile"] + self.config["npvrPIN"] = config.config["nextpvr"]["pin"] + self.config["npvrURL"] = ('%s%s:%s' % + ("https://" if config.config["nextpvr"]["ssl"] else "http://", + config.config["nextpvr"]["address"], + str(config.config["nextpvr"]["port"]), + )) + + def _check_sid(self): + if 'sid' not in self.config: + if os.path.isfile(self.sidfile): + with open(self.sidfile, 'r') as text_file: + self.config['sid'] = text_file.read() + print('Read SID from file.') + else: + self._get_sid() + + return True + + def _get_sid(self): + sid = '' + salt = '' + clientKey = '' + + initiate_url = "%s/service?method=session.initiate&ver=1.0&device=fhdhr" % self.config['npvrURL'] + + initiate_req = urllib.request.urlopen(initiate_url) + initiate_dict = xmltodict.parse(initiate_req) + + sid = initiate_dict['rsp']['sid'] + salt = initiate_dict['rsp']['salt'] + md5PIN = hashlib.md5(self.config['npvrPIN'].encode('utf-8')).hexdigest() + string = ':%s:%s' % (md5PIN, salt) + clientKey = hashlib.md5(string.encode('utf-8')).hexdigest() + + login_url = '%s/service?method=session.login&sid=%s&md5=%s' % (self.config['npvrURL'], sid, clientKey) + login_req = urllib.request.urlopen(login_url) + login_dict = xmltodict.parse(login_req) + + if login_dict['rsp']['allow_watch'] == "true": + self.config['sid'] = sid + with open(self.sidfile, 'w') as text_file: + text_file.write(self.config['sid']) + print('Wrote SID to file.') + else: + print("NextPVR Login Failed") + self.config['sid'] = '' + + +def xmltimestamp_nextpvr(epochtime): + xmltime = datetime.datetime.fromtimestamp(int(epochtime)/1000) + xmltime = str(xmltime.strftime('%Y%m%d%H%M%S')) + " +0000" + return xmltime + + +def duration_nextpvr_minutes(starttime, endtime): + return ((int(endtime) - int(starttime))/1000/60) + + +class proxyserviceFetcher(): + + def __init__(self, config): + self.config = config.config + + self.epg_cache = None + self.epg_cache_file = config.config["nextpvr"]["epg_cache"] + + self.servicename = "NextPVRProxy" + + self.urls = {} + self.url_assembler() + + self.auth = NextPVR_Auth(config) + + self.epg_cache = self.epg_cache_open() + + def epg_cache_open(self): + epg_cache = None + if os.path.isfile(self.epg_cache_file): + with open(self.epg_cache_file, 'r') as epgfile: + epg_cache = json.load(epgfile) + return epg_cache + + def url_assembler(self): + pass + + def get_channels(self): + self.auth._check_sid() + + url = ('%s%s:%s/service?method=channel.list&sid=%s' % + ("https://" if self.config["nextpvr"]["ssl"] else "http://", + self.config["nextpvr"]["address"], + str(self.config["nextpvr"]["port"]), + self.auth.config['sid'] + )) + + r = urllib.request.urlopen(url) + data_dict = xmltodict.parse(r) + + if 'channels' not in list(data_dict['rsp'].keys()): + print("could not retrieve channel list") + return [] + + channel_o_list = data_dict['rsp']['channels']['channel'] + + channel_list = [] + for c in channel_o_list: + dString = json.dumps(c) + channel_dict = eval(dString) + channel_list.append(channel_dict) + return channel_list + + def get_station_list(self, base_url): + station_list = [] + + for c in self.get_channels(): + if self.config["fakehdhr"]["stream_type"] == "ffmpeg": + watchtype = "ffmpeg" + else: + watchtype = "direct" + url = ('%s%s/watch?method=%s&channel=%s' % + ("http://", + base_url, + watchtype, + c['formatted-number'] + )) + station_list.append( + { + 'GuideNumber': str(c['formatted-number']), + 'GuideName': c['name'], + 'URL': url + }) + return station_list + + def get_station_total(self): + total_channels = 0 + for c in self.get_channels(): + total_channels += 1 + return total_channels + + def get_channel_streams(self): + streamdict = {} + for c in self.get_channels(): + url = ('%s%s:%s/live?channel=%s&client=%s' % + ("https://" if self.config["nextpvr"]["ssl"] else "http://", + self.config["nextpvr"]["address"], + str(self.config["nextpvr"]["port"]), + str(c["formatted-number"]), + str(c["formatted-number"]), + )) + streamdict[str(c["formatted-number"])] = url + return streamdict + + def get_channel_thumbnail(self, channel_id): + channel_thumb_url = ("%s%s:%s/service?method=channel.icon&channel_id=%s" % + ("https://" if self.config["nextpvr"]["ssl"] else "http://", + self.config["nextpvr"]["address"], + str(self.config["nextpvr"]["port"]), + str(channel_id) + )) + return channel_thumb_url + + def get_content_thumbnail(self, content_id): + self.auth._check_sid() + item_thumb_url = ("%s%s:%s/service?method=channel.show.artwork&sid=%s&event_id=%s" % + ("https://" if self.config["nextpvr"]["ssl"] else "http://", + self.config["nextpvr"]["address"], + str(self.config["nextpvr"]["port"]), + self.auth.config['sid'], + str(content_id) + )) + return item_thumb_url + + def update_epg(self): + print('Updating NextPVR EPG cache file.') + self.auth._check_sid() + + programguide = {} + + for c in self.get_channels(): + if str(c["formatted-number"]) not in list(programguide.keys()): + programguide[str(c["formatted-number"])] = {} + + channel_thumb_path = ("/images?source=proxy&type=channel&id=%s" % (str(c['id']))) + programguide[str(c["formatted-number"])]["thumbnail"] = channel_thumb_path + + if "name" not in list(programguide[str(c["formatted-number"])].keys()): + programguide[str(c["formatted-number"])]["name"] = c["name"] + + if "callsign" not in list(programguide[str(c["formatted-number"])].keys()): + programguide[str(c["formatted-number"])]["callsign"] = c["name"] + + if "id" not in list(programguide[str(c["formatted-number"])].keys()): + programguide[str(c["formatted-number"])]["id"] = c["id"] + + if "number" not in list(programguide[str(c["formatted-number"])].keys()): + programguide[str(c["formatted-number"])]["number"] = c["formatted-number"] + + if "listing" not in list(programguide[str(c["formatted-number"])].keys()): + programguide[str(c["formatted-number"])]["listing"] = [] + + epg_url = ('%s%s:%s/service?method=channel.listings&channel_id=%s' % + ("https://" if self.config["nextpvr"]["ssl"] else "http://", + self.config["nextpvr"]["address"], + str(self.config["nextpvr"]["port"]), + str(c["id"]), + )) + epg_req = urllib.request.urlopen(epg_url) + epg_dict = xmltodict.parse(epg_req) + + for program_listing in epg_dict["rsp"]["listings"]: + for program_item in epg_dict["rsp"]["listings"][program_listing]: + if not isinstance(program_item, str): + dirty_prog_dict = {} + for programkey in list(program_item.keys()): + dirty_prog_dict[programkey] = program_item[programkey] + + clean_prog_dict = {} + + clean_prog_dict["time_start"] = xmltimestamp_nextpvr(dirty_prog_dict["start"]) + clean_prog_dict["time_end"] = xmltimestamp_nextpvr(dirty_prog_dict["end"]) + clean_prog_dict["duration_minutes"] = duration_nextpvr_minutes(dirty_prog_dict["start"], dirty_prog_dict["end"]) + + item_thumb_path = ("/images?source=proxy&type=content&id=%s" % (str(dirty_prog_dict['id']))) + clean_prog_dict["thumbnail"] = item_thumb_path + + if 'name' not in list(dirty_prog_dict.keys()): + dirty_prog_dict["name"] = "Unavailable" + elif not dirty_prog_dict["name"]: + dirty_prog_dict["name"] = "Unavailable" + clean_prog_dict["title"] = dirty_prog_dict["name"] + + if 'genre' not in list(dirty_prog_dict.keys()): + clean_prog_dict["genres"] = [] + else: + clean_prog_dict["genres"] = dirty_prog_dict['genre'].split(",") + + if 'subtitle' not in list(dirty_prog_dict.keys()): + dirty_prog_dict["subtitle"] = "Unavailable" + clean_prog_dict["sub-title"] = dirty_prog_dict["subtitle"] + + if dirty_prog_dict['subtitle'].startswith("Movie:"): + clean_prog_dict['releaseyear'] = dirty_prog_dict['subtitle'].split("Movie:")[-1] + else: + clean_prog_dict['releaseyear'] = None + + if 'description' not in list(dirty_prog_dict.keys()): + dirty_prog_dict["description"] = "Unavailable" + elif dirty_prog_dict['description']: + dirty_prog_dict["description"] = "Unavailable" + clean_prog_dict["description"] = dirty_prog_dict["description"] + + if 'rating' not in list(dirty_prog_dict.keys()): + dirty_prog_dict['rating'] = "N/A" + clean_prog_dict['rating'] = dirty_prog_dict['rating'] + + if 'season' in list(dirty_prog_dict.keys()) and 'episode' in list(dirty_prog_dict.keys()): + clean_prog_dict["seasonnumber"] = dirty_prog_dict['season'] + clean_prog_dict["episodenumber"] = dirty_prog_dict['episode'] + clean_prog_dict["episodetitle"] = clean_prog_dict["sub-title"] + else: + if "movie" not in clean_prog_dict["genres"]: + clean_prog_dict["episodetitle"] = clean_prog_dict["sub-title"] + + # TODO isNEW + + programguide[str(c["formatted-number"])]["listing"].append(clean_prog_dict) + + self.epg_cache = programguide + with open(self.epg_cache_file, 'w') as epgfile: + epgfile.write(json.dumps(programguide, indent=4)) + print('Wrote updated NextPVR EPG cache file.') + return programguide diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..6fcb3c2 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,4 @@ +requests +gevent +flask +image diff --git a/ssdpserver/__init__.py b/ssdpserver/__init__.py new file mode 100644 index 0000000..281fd88 --- /dev/null +++ b/ssdpserver/__init__.py @@ -0,0 +1,239 @@ +# Licensed under the MIT license +# http://opensource.org/licenses/mit-license.php + +# Copyright 2005, Tim Potter +# Copyright 2006 John-Mark Gurney +# Copyright (C) 2006 Fluendo, S.A. (www.fluendo.com). +# Copyright 2006,2007,2008,2009 Frank Scholz +# Copyright 2016 Erwan Martin +# +# Implementation of a SSDP server. +# + +import random +import time +import socket +import logging +from email.utils import formatdate +from errno import ENOPROTOOPT + +SSDP_ADDR = '239.255.255.250' + + +logger = logging.getLogger() + + +# mostly from https://github.com/ZeWaren/python-upnp-ssdp-example +def ssdpServerProcess(config): + ssdp = SSDPServer() + ssdp.ssdp_port = 1900 + ssdp.register('local', + 'uuid:' + config.config["main"]["uuid"] + '::upnp:rootdevice', + 'upnp:rootdevice', + 'http://' + config.config["fakehdhr"]["discovery_address"] + ':' + + config.config["fakehdhr"]["port"] + '/device.xml') + try: + ssdp.run() + except KeyboardInterrupt: + pass + + +class SSDPServer: + """A class implementing a SSDP server. The notify_received and + searchReceived methods are called when the appropriate type of + datagram is received by the server.""" + known = {} + + def __init__(self): + self.sock = None + + def run(self): + self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + if hasattr(socket, "SO_REUSEPORT"): + try: + self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) + except socket.error as le: + # RHEL6 defines SO_REUSEPORT but it doesn't work + if le.errno == ENOPROTOOPT: + pass + else: + raise + + addr = socket.inet_aton(SSDP_ADDR) + interface = socket.inet_aton('0.0.0.0') + cmd = socket.IP_ADD_MEMBERSHIP + self.sock.setsockopt(socket.IPPROTO_IP, cmd, addr + interface) + self.sock.bind(('0.0.0.0', self.ssdp_port)) + self.sock.settimeout(1) + + while True: + try: + data, addr = self.sock.recvfrom(1024) + self.datagram_received(data, addr) + except socket.timeout: + continue + self.shutdown() + + def shutdown(self): + for st in self.known: + if self.known[st]['MANIFESTATION'] == 'local': + self.do_byebye(st) + + def datagram_received(self, data, host_port): + """Handle a received multicast datagram.""" + + (host, port) = host_port + + try: + header, payload = data.decode().split('\r\n\r\n')[:2] + except ValueError as err: + logger.error(err) + return + + lines = header.split('\r\n') + cmd = lines[0].split(' ') + lines = [x.replace(': ', ':', 1) for x in lines[1:]] + lines = [x for x in lines if len(x) > 0] + + headers = [x.split(':', 1) for x in lines] + headers = dict([(x[0].lower(), x[1]) for x in headers]) + + logger.info('SSDP command %s %s - from %s:%d' % (cmd[0], cmd[1], host, port)) + logger.debug('with headers: {}.'.format(headers)) + if cmd[0] == 'M-SEARCH' and cmd[1] == '*': + # SSDP discovery + self.discovery_request(headers, (host, port)) + elif cmd[0] == 'NOTIFY' and cmd[1] == '*': + # SSDP presence + logger.debug('NOTIFY *') + else: + logger.warning('Unknown SSDP command %s %s' % (cmd[0], cmd[1])) + + def register(self, manifestation, usn, st, location, cache_control='max-age=1800', silent=False, + host=None): + """Register a service or device that this SSDP server will + respond to.""" + + logging.info('Registering %s (%s)' % (st, location)) + + self.known[usn] = {} + self.known[usn]['USN'] = usn + self.known[usn]['LOCATION'] = location + self.known[usn]['ST'] = st + self.known[usn]['EXT'] = '' + self.known[usn]['SERVER'] = "fHDHR Server" + self.known[usn]['CACHE-CONTROL'] = cache_control + + self.known[usn]['MANIFESTATION'] = manifestation + self.known[usn]['SILENT'] = silent + self.known[usn]['HOST'] = host + self.known[usn]['last-seen'] = time.time() + + if manifestation == 'local' and self.sock: + self.do_notify(usn) + + def unregister(self, usn): + logger.info("Un-registering %s" % usn) + del self.known[usn] + + def is_known(self, usn): + return usn in self.known + + def send_it(self, response, destination, delay, usn): + logger.debug('send discovery response delayed by %ds for %s to %r' % (delay, usn, destination)) + try: + self.sock.sendto(response.encode(), destination) + except (AttributeError, socket.error) as msg: + logger.warning("failure sending out byebye notification: %r" % msg) + + def discovery_request(self, headers, host_port): + """Process a discovery request. The response must be sent to + the address specified by (host, port).""" + + (host, port) = host_port + + logger.info('Discovery request from (%s,%d) for %s' % (host, port, headers['st'])) + logger.info('Discovery request for %s' % headers['st']) + + # Do we know about this service? + for i in list(self.known.values()): + if i['MANIFESTATION'] == 'remote': + continue + if headers['st'] == 'ssdp:all' and i['SILENT']: + continue + if i['ST'] == headers['st'] or headers['st'] == 'ssdp:all': + response = ['HTTP/1.1 200 OK'] + + usn = None + for k, v in list(i.items()): + if k == 'USN': + usn = v + if k not in ('MANIFESTATION', 'SILENT', 'HOST'): + response.append('%s: %s' % (k, v)) + + if usn: + response.append('DATE: %s' % formatdate(timeval=None, localtime=False, usegmt=True)) + + response.extend(('', '')) + delay = random.randint(0, int(headers['mx'])) + + self.send_it('\r\n'.join(response), (host, port), delay, usn) + + def do_notify(self, usn): + """Do notification""" + + if self.known[usn]['SILENT']: + return + logger.info('Sending alive notification for %s' % usn) + + resp = [ + 'NOTIFY * HTTP/1.1', + 'HOST: %s:%d' % (SSDP_ADDR, self.ssdp_port), + 'NTS: ssdp:alive', + ] + stcpy = dict(list(self.known[usn].items())) + stcpy['NT'] = stcpy['ST'] + del stcpy['ST'] + del stcpy['MANIFESTATION'] + del stcpy['SILENT'] + del stcpy['HOST'] + del stcpy['last-seen'] + + resp.extend([': '.join(x) for x in list(stcpy.items())]) + resp.extend(('', '')) + logger.debug('do_notify content', resp) + try: + self.sock.sendto('\r\n'.join(resp).encode(), (SSDP_ADDR, self.ssdp_port)) + self.sock.sendto('\r\n'.join(resp).encode(), (SSDP_ADDR, self.ssdp_port)) + except (AttributeError, socket.error) as msg: + logger.warning("failure sending out alive notification: %r" % msg) + + def do_byebye(self, usn): + """Do byebye""" + + logger.info('Sending byebye notification for %s' % usn) + + resp = [ + 'NOTIFY * HTTP/1.1', + 'HOST: %s:%d' % (SSDP_ADDR, self.ssdp_port), + 'NTS: ssdp:byebye', + ] + try: + stcpy = dict(list(self.known[usn].items())) + stcpy['NT'] = stcpy['ST'] + del stcpy['ST'] + del stcpy['MANIFESTATION'] + del stcpy['SILENT'] + del stcpy['HOST'] + del stcpy['last-seen'] + resp.extend([': '.join(x) for x in list(stcpy.items())]) + resp.extend(('', '')) + logger.debug('do_byebye content', resp) + if self.sock: + try: + self.sock.sendto('\r\n'.join(resp), (SSDP_ADDR, self.ssdp_port)) + except (AttributeError, socket.error) as msg: + logger.error("failure sending out byebye notification: %r" % msg) + except KeyError as msg: + logger.error("error building byebye notification: %r" % msg)