Skip to content

Instantly share code, notes, and snippets.

@marios8543
Last active July 14, 2020 22:42
Show Gist options
  • Save marios8543/e978fadb1f935cd58c764588ac5adafd to your computer and use it in GitHub Desktop.
Save marios8543/e978fadb1f935cd58c764588ac5adafd to your computer and use it in GitHub Desktop.
#Antenna.gr Downloader - marios8543 | github.com/marios8543
#MIT License
from aiohttp import ClientSession
from aiofiles import open as aopen
from asyncio import get_event_loop, Semaphore, sleep, Event
from os import getenv, path, mkdir
from sys import argv
from logging import info, error, debug, warn
web = ClientSession()
class Segment:
def __init__(self, url, title, idx):
self.url = url
self.title = title
self.idx = idx
self.res = None
async def get(self):
while True:
res = await web.get(self.url)
if res.status == 200:
self.res = await res.read()
return
error("Could not get segment {} of {} ({}). Retrying...".format(self.idx+1, self.title, await res.text()))
await sleep(3)
class Player:
def __init__(self, dc):
self.title = dc['title']
self.url = dc['url']
self.show = dc['Show']
self.dl_queue = []
self.dl_sem = Semaphore(int(getenv("MAX_DOWNLOADS", "5")))
async def download(self):
info("Commencing download of {}".format(self.title))
await self._populate_segments(await self._get_master_url())
await self._downloader()
async def _get_master_url(self):
res = await web.get(self.url)
if res.status == 200:
res = await res.text()
url = res.splitlines(False)[2]
if not url.startswith("https://"):
raise ValueError("Could not parse master.m3u8")
debug("Got master URL: {}".format(url))
return url
raise ValueError("Could not get master.m3u8")
async def _populate_segments(self, master_url):
res = await web.get(master_url)
if res.status == 200:
debug("Populating download queue with segments")
res = (await res.text()).splitlines(False)
i = 0
for v in res:
if v.startswith("https://"):
self.dl_queue.append(Segment(v, self.title, i))
i+=1
return
raise ValueError("Could not get segments")
async def _downloader(self):
debug("Starting downloader coroutine")
ev = Event()
_i = [0]
def inc():
_i[0] += 1
if _i[0] == len(self.dl_queue):
ev.set()
for item in self.dl_queue:
await self.dl_sem.acquire()
get_event_loop().create_task(item.get()).add_done_callback(lambda _: (
self.dl_sem.release(),
inc()
))
await ev.wait()
async with aopen(self.title+".ts", "wb+") as f:
for item in self.dl_queue:
await f.write(item.res)
info("Downloaded {}".format(self.title))
async def get_player(cid):
res = await web.get("https://www.antenna.gr/templates/data/player", params={"cid": cid})
if res.status == 200:
show = Player(await res.json())
debug("Got player for CID {}".format(cid))
return show
raise ValueError("Could not parse player: {}".format(await res.text()))
if __name__ == "__main__":
async def _():
p = await get_player(argv[1])
await p.download()
get_event_loop().run_until_complete(_())
from aiohttp import ClientSession
from pyquery import PyQuery
from sys import argv
from downloader import main
from time import sleep
from asyncio import get_event_loop
web = ClientSession()
def ruc(coro):
return get_event_loop().run_until_complete(coro)
def id_from_link(link):
return link.split("/")[2]
def get_episodes(aid):
page = 1
ids = []
while True:
res = ruc(web.get("https://www.antenna.gr/templates/data/morevideos", params={"aid":aid, "p":page}))
if res.status == 200:
root = PyQuery(ruc(res.text()))
l= []
for el in root.find("article"):
el = el.find("a")
link = el.attrib["href"]
l.append(id_from_link(link))
ids.extend(l)
if not l:
break
page+=1
return ids
if __name__ == '__main__':
ids = get_episodes(argv[1])
for i in ids:
main(i)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment