Repository URL to install this package:
|
Version:
4.03-20230705 ▾
|
enigma2-plugin-extensions-xstreamity
/
usr
/
lib
/
enigma2
/
python
/
Plugins
/
Extensions
/
XStreamity
/
update.py
|
|---|
#!/usr/bin/python
# -*- coding: utf-8 -*-
from .plugin import playlists_json, pythonVer, cfg, hdr
from xml.etree.cElementTree import iterparse
from twisted.web.client import downloadPage
from requests.adapters import HTTPAdapter, Retry
try:
from urlparse import urlparse
except:
from urllib.parse import urlparse
import calendar
import json
import os
import requests
import time
import twisted.python.runtime
try:
from http.client import HTTPConnection
HTTPConnection.debuglevel = 0
except:
from httplib import HTTPConnection
HTTPConnection.debuglevel = 0
requests.packages.urllib3.disable_warnings()
# https twisted client hack #
try:
from twisted.internet import ssl
from twisted.internet._sslverify import ClientTLSOptions
sslverify = True
except:
sslverify = False
if sslverify:
class SNIFactory(ssl.ClientContextFactory):
def __init__(self, hostname=None):
self.hostname = hostname
def getContext(self):
ctx = self._contextFactory(self.method)
if self.hostname:
ClientTLSOptions(self.hostname, ctx)
return ctx
def quickptime(str):
return time.struct_time((int(str[0:4]), int(str[4:6]), int(str[6:8]), int(str[8:10]), int(str[10:12]), 0, 1, -1, 0))
def get_time_utc(timestring, fdateparse):
try:
values = timestring.split(" ")
tm = fdateparse(values[0])
timegm = calendar.timegm(tm)
timegm -= (3600 * int(values[1]) / 100)
return timegm
except Exception as e:
print("[XMLTVConverter] get_time_utc error:", e)
return 0
class XStreamity_Update:
def __init__(self):
# print("****** update ****")
self.epgfolder = ""
self.epgxmlfile = ""
self.epgjsonfile = ""
self.processJsonFile()
def clear_caches(self):
try:
os.system("echo 1 > /proc/sys/vm/drop_caches")
os.system("echo 2 > /proc/sys/vm/drop_caches")
os.system("echo 3 > /proc/sys/vm/drop_caches")
except:
pass
def checkRedirect(self, url):
# print("*** check redirect ***")
x = ""
retries = Retry(total=3, backoff_factor=1)
adapter = HTTPAdapter(max_retries=retries)
http = requests.Session()
http.mount("http://", adapter)
http.mount("https://", adapter)
try:
x = http.get(url, headers=hdr, timeout=30, verify=False, stream=True)
url = x.url
x.close()
return str(url)
except Exception as e:
print(e)
return str(url)
def processJsonFile(self):
# print("*** processJsonFile ***")
try:
with open(playlists_json, "r") as f:
self.playlists_all = json.load(f)
except Exception as e:
print(e)
return
self.urllist = []
for playlist in self.playlists_all:
if "user_info" in playlist and "auth" in playlist["user_info"] and str(playlist["user_info"]["auth"]) == "1":
domain = playlist["playlist_info"]["domain"]
name = playlist["playlist_info"]["name"]
xmltv = playlist["playlist_info"]["xmltv_api"]
epglocation = str(cfg.epglocation.value)
epgfolder = os.path.join(epglocation, str(name))
epgxmlfile = os.path.join(epgfolder, "epg.xml")
epgjsonfile = os.path.join(epgfolder, "epg.json")
exists = any(str(name) == str(x[0]) for x in self.urllist)
if exists:
continue
self.urllist.append([domain, xmltv, epgxmlfile, epgjsonfile])
if not os.path.exists(epgfolder):
os.makedirs(epgfolder)
self.processPlaylist()
self.clear_caches()
def processPlaylist(self):
# print("*** processPlaylist ***")
if self.urllist:
xmltv = self.urllist[0][1]
try:
self.downloadxmltv(str(xmltv))
except Exception as e:
print(e)
# new epg code
def downloadxmltv(self, url):
# print("**** downloadxmltv ***")
epgxmlfile = self.urllist[0][2]
url = self.checkRedirect(url)
time.sleep(1)
try:
parsed = urlparse(url)
domain = parsed.hostname
scheme = parsed.scheme
if pythonVer == 3:
url = url.encode()
if scheme == "https" and sslverify:
sniFactory = SNIFactory(domain)
downloadPage(url, epgxmlfile, sniFactory, timeout=120).addCallback(self.downloadComplete).addErrback(self.downloadFailed)
else:
downloadPage(url, epgxmlfile, timeout=120).addCallback(self.downloadComplete).addErrback(self.downloadFailed)
except Exception as e:
print(e)
try:
os.remove(epgxmlfile)
except Exception as e:
print(e)
self.downloadFailed()
def downloadComplete(self, data=None):
# print("**** downloadComplete ***")
if twisted.python.runtime.platform.supportsThreads():
from twisted.internet import threads
try:
d = threads.deferToThread(self.buildjson)
d.addErrback(self.createJsonFail)
except Exception as e:
print(e)
try:
self.buildjson()
except Exception as e:
print(e)
self.createJsonFail(e)
else:
try:
self.buildjson()
except Exception as e:
print(e)
self.createJsonFail(e)
def downloadFailed(self, data=None):
# print("*** downloadFailed ***")
print(data)
self.urllist.pop(0)
if self.urllist:
self.processPlaylist()
else:
return
def createJsonFail(self, data=None):
# print("**** createjsonfail ***")
epgjsonfile = self.urllist[0][3]
print(("Create Json failed:", data))
try:
os.remove(epgjsonfile)
except:
pass
self.urllist.pop(0)
if self.urllist:
self.processPlaylist()
else:
return
def buildjson(self):
# print("*** buildjson ***")
epgitems = {}
nowtime = calendar.timegm(time.gmtime())
epgjsonfile = self.urllist[0][3]
epgxmlfile = self.urllist[0][2]
for channel, start, stop, title, desc in self.buildjson2():
start = get_time_utc(start, quickptime)
stop = get_time_utc(stop, quickptime)
if start < nowtime + (3600 * 24) and stop > start and stop > nowtime:
if channel in epgitems:
epgitems[channel].append([start, stop, title, desc])
else:
epgitems[channel] = [[start, stop, title, desc]]
with open(epgjsonfile, "w") as jsonFile:
json.dump(epgitems, jsonFile, ensure_ascii=False)
try:
os.remove(epgxmlfile)
except:
pass
epgitems.clear()
self.urllist.pop(0)
if self.urllist:
self.processPlaylist()
else:
return
def buildjson2(self):
# print("***** buildjson2 *****")
fileobj = self.urllist[0][2]
try:
for event, elem in iterparse(fileobj):
if elem.tag == "channel":
elem.clear()
if elem.tag == "programme":
channel = elem.get("channel")
if channel:
try:
start = elem.get("start")
stop = elem.get("stop")
except:
continue
try:
title = elem.find("title").text
except:
title = ""
try:
desc = elem.find("desc").text
except:
desc = ""
if channel and start and stop:
yield channel.lower(), start, stop, title or "", desc or ""
elem.clear()
except Exception as e:
print("*** bad data in xml file *** %s" % fileobj)
print(e)