stream-api/backend/config.py

207 lines
6.7 KiB
Python

import json
import sys
import pprint
import os
import re
import base64
import logging
import distutils.util
import asyncio
import tornado.web
import tornado.routing
import config
import stream_providers
import aiohttp
providers = {}
providers["nrk"] = "https://tv.nrk.no"
providers["nrk_web"] = "https://nrk.no"
providers["svt"] = "https://svtplay.se"
providers["youtube"] = "https://www.youtube.com/watch?v="
providers["twitch"] = "https://twitch.tv"
providers["twitter"] = "https://twitter.com"
nextcloud_server = os.environ.get("NEXTCLOUD_SERVER")
if nextcloud_server is not None:
providers["nextcloud"] = nextcloud_server
seafile_server = os.environ.get("SEAFILE_SERVER")
if seafile_server is not None:
providers["seafile"] = seafile_server
playlist = None
icecast_server = os.environ.get("ICECAST_SERVER")
stream_server = os.environ.get("STREAM_SERVER")
proxy_server = os.environ.get("PROXY_SERVER")
class ProxyElem():
def __init__(self, proxy, region):
self.proxy = proxy
self.region = region
def local(self):
timeout = aiohttp.ClientTimeout(total=5)
return aiohttp.ClientSession(timeout=timeout)
def __repr__(self):
return f"<region=<{str(self.region)}> proxy=<{str(self.proxy)}>>"
async def proxy_url(self, urls):
clean_urls = []
for url in urls:
if isinstance(url, tuple):
clean_urls.append(url[0])
else:
clean_urls.append(url)
if not isinstance(proxy_server, str):
return clean_urls
jdata = None
data_list = []
for url in urls:
data = {}
if isinstance(url, str):
data["upstream"] = url
elif isinstance(url, tuple):
if isinstance(url[0], str):
data["upstream"] = url[0]
if isinstance(url[1], str):
data["ctype"] = url[1]
data["region"] = self.region
data_list.append(data)
try:
async with self.local() as session:
resp = await session.post(proxy_server, json=data_list)
text = await resp.text()
jdata = json.loads(text)
except Exception as e:
logger.info(e)
if isinstance(jdata, list):
ret_data = []
for src, dst in zip(clean_urls, jdata):
if isinstance(src, str):
ret_data.append(dst)
else:
ret_data.append(None)
return ret_data
else:
return clean_urls
proxies = {}
new_providers = {}
for key in providers:
region_expr = re.compile(f'^{key}_region(_[a-z][a-z])?[0-9]+$', re.IGNORECASE)
region_matches = list(filter(region_expr.match, os.environ.keys()))
proxy_expr = re.compile(f'^{key}_proxy(_[a-z][a-z])?[0-9]+$', re.IGNORECASE)
proxy_matches = list(filter(proxy_expr.match, os.environ.keys()))
proxy_current = []
proxy_current_keys = set()
proxy_current_keys.add(key)
proxy_countries = []
proxy_empty = True
region_current = []
region_current_keys = set()
region_current_keys.add(key)
region_countries = []
region_empty = True
for match in proxy_matches:
proxy_country_groups = proxy_expr.match(match.lower()).groups()
proxy_country = None
pos = len(proxy_country_groups) - 1
if pos >= 0:
country_temp = proxy_country_groups[pos]
if isinstance(country_temp, str):
proxy_country = country_temp.strip("_")
proxy_current_keys.add(f'{key}_{proxy_country}')
proxy = os.environ.get(match)
if proxy is not None:
proxy_current.append(proxy)
proxy_countries.append(proxy_country)
if proxy_country is None:
proxy_empty = False
for match in region_matches:
region_country_groups = region_expr.match(match.lower()).groups()
region_country = None
pos = len(region_country_groups) - 1
if pos >= 0:
country_temp = region_country_groups[pos]
if isinstance(country_temp, str):
region_country = country_temp.strip("_")
region_current_keys.add(f'{key}_{region_country}')
region = os.environ.get(match)
if region is not None:
region_current.append(region)
region_countries.append(region_country)
if region_country is None:
region_empty = False
for elem in proxy_current_keys:
proxies[elem] = []
new_providers[elem] = providers[key]
for proxy, region, country in zip(proxy_current, region_current, proxy_countries):
new_key = key
if country is not None:
new_key = f'{key}_{country}'
proxies[new_key].append(ProxyElem(proxy, region))
for elem in proxy_current_keys:
if len(proxies[elem]) == 0:
proxies[elem].append(ProxyElem(None, None))
pprint.pp(proxies)
providers = new_providers
proxy_keys = []
for proxy_provider in proxies.values():
for proxy in proxy_provider:
if isinstance(proxy, ProxyElem) and isinstance(proxy.proxy, str):
proxy_keys.append(proxy.proxy)
stream_providers.setup(proxy_keys)
if icecast_server is not None and stream_server is not None:
try:
with open("/app/sources.json", "r") as f:
data = json.loads(f.read())
playlist = "#EXTM3U\n"
for key in data:
current = data[key]
name = current["name"]
radio = current["radio"]
if radio:
playlist += f'#EXTINF:0 radio="true", {name}\n'
playlist += icecast_server + key + "\n"
else:
playlist += f'#EXTINF:0 radio="false", {name}\n'
playlist += stream_server + key + "\n"
except Exception as e:
logger.info(e)
template_html = None
template_script = None
videojs_version = None
font_awesome_version = None
custom_style = None
favicon = None
try:
with open("/app/index.html", "r") as f:
template_html = tornado.template.Template(f.read().strip())
with open("/app/script.js", "r") as f:
template_script = tornado.template.Template(f.read().strip())
with open("/app/version/video.js.txt", "r") as f:
videojs_version = f.read().strip()
with open("/app/version/chromecast.txt", "r") as f:
chromecast_version = f.read().strip()
with open("/app/version/font-awesome.txt", "r") as f:
font_awesome_version = f.read().strip()
with open("/app/favicon.png", "rb") as f:
favicon = f.read()
with open("/app/style.css", "r") as f:
custom_style = f.read()
except Exception as e:
logger.info(e)