#!/usr/bin/python3
from bs4 import BeautifulSoup
import json
import os
import re
import streamlink
import subprocess
import sys
from urllib import request

# set to true for development
CACHE_RESULTS = False

# Change to whatever you like
USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0"


class StatusDisplay:
	"""A context manager for updating a one-line display.
	"""
	def __init__(self, dest_f=sys.stdout):
		self.dest_f = dest_f
		self.clearer = "\r\n"
	
	def update(self, new_content):
		self.dest_f.write(self.clearer+new_content)
		self.dest_f.flush()
		self.clearer = "\r"+(" "*len(new_content))+"\r"
	
	def __enter__(self):
		self.dest_f.write(self.clearer)
		self.dest_f.flush()
		return self

	def __exit__(self, *args):
		self.dest_f.write("\r\n")
		self.dest_f.flush()


def get_with_cache(url, bypass_cache=False, extra_headers={}):
	if url.startswith("//"):
		url = "http:"+url

	cache_name = re.sub("[^\w]+", "", url)+".cache"
	if not bypass_cache and CACHE_RESULTS and os.path.exists(cache_name):
		doc = open(cache_name, "rb").read()
	else:
		headers = {"User-Agent": USER_AGENT}
		headers.update(extra_headers)
		req = request.Request(url, headers=headers)
		f = request.urlopen(req)
		doc = f.read()
		f.close()
		if CACHE_RESULTS:
			with open(cache_name, "wb") as f:
				f.write(doc)
	return doc


def retrieve_video(disp):
	disp.update("Pulling embedding HTML...")
	doc = get_with_cache("https://www.wdrmaus.de/aktuelle-sendung/index.php5"
		).decode("utf-8")
	tree = BeautifulSoup(doc, "lxml")
	data_src = tree.find_all("a", href="#"
			)[0].get("data-extension-ard")
	data_ext = json.loads(data_src.replace("'", '"'))

	# Oh, why javascript and no simple json?
	disp.update("Getting meta javascript...")
	json_content = get_with_cache(data_ext["mediaObj"]["url"])
	store_and_play = json.loads(
		re.sub(".*?\(", "", json_content.decode("utf-8"))[:-2])
	m3u_URL = store_and_play["mediaResource"]["dflt"]["videoURL"]
	if m3u_URL.startswith("//"):
		m3u_URL = "http:"+m3u_URL
	disp.update("Fetching with streamlink...")

	session = streamlink.Streamlink()
	streams = session.streams(m3u_URL)
	stream = streams["360p"]

	src = stream.open()
	total_size = 0
	with open("maus.mpg", "wb") as dest:
		while True:
			data = src.read(1000000)
			if not data:
				break
			dest.write(data)
			total_size += len(data)
			disp.update("%d kB"%(total_size/1000))

	disp.update("Done.")


def main():
	with StatusDisplay() as disp:
		retrieve_video(disp)


if __name__=="__main__":
	main()
