184 lines
4.6 KiB
Python
184 lines
4.6 KiB
Python
import time
|
|
from dataclasses import dataclass
|
|
import requests
|
|
import re
|
|
import subprocess
|
|
import shutil
|
|
|
|
|
|
_token: "Token" = None
|
|
|
|
|
|
def _cookies() -> dict[str, str]:
|
|
if _token is None:
|
|
return {}
|
|
return _token.cookies()
|
|
|
|
|
|
@dataclass
|
|
class Token():
|
|
auth_token: str
|
|
session_id: str
|
|
session_ci: str
|
|
|
|
def cookies(self):
|
|
cookies = {}
|
|
|
|
if self.auth_token is not None:
|
|
cookies["SimpleSAMLAuthToken"] = self.auth_token
|
|
|
|
if self.session_id is not None:
|
|
cookies["SimpleSAMLSessionID"] = self.session_id
|
|
|
|
if self.session_ci is not None:
|
|
cookies["session_ci"] = self.session_ci
|
|
|
|
return cookies
|
|
|
|
|
|
@dataclass
|
|
class ClipDetails():
|
|
clip_id: str
|
|
|
|
combined_media_id: str = None
|
|
combined_playlist_url: str = None
|
|
camera_media_id: str = None
|
|
camera_playlist_url: str = None
|
|
slides_media_id: str = None
|
|
slides_playlist_url: str = None
|
|
|
|
def media_ids(self):
|
|
return [id for id in [
|
|
self.combined_media_id,
|
|
self.camera_media_id,
|
|
self.slides_media_id,
|
|
] if id is not None]
|
|
|
|
def playlist_urls(self):
|
|
return [url for url in [
|
|
self.combined_playlist_url,
|
|
self.camera_playlist_url,
|
|
self.slides_playlist_url,
|
|
] if url is not None]
|
|
|
|
|
|
def set_token(auth_token: str, session_id: str, session_ci: str):
|
|
global _token
|
|
_token = Token(auth_token, session_id, session_ci)
|
|
|
|
|
|
def load_token(auth_url: str):
|
|
global _token
|
|
|
|
from selenium import webdriver
|
|
|
|
driver = webdriver.Firefox()
|
|
|
|
driver.get(auth_url)
|
|
|
|
while not driver.current_url.startswith('https://www.fau.tv/'):
|
|
time.sleep(0.5)
|
|
|
|
def get_value(cookie):
|
|
if cookie is None:
|
|
return None
|
|
return cookie.get("value")
|
|
|
|
_token = Token(
|
|
auth_token=get_value(driver.get_cookie("SimpleSAMLAuthToken")),
|
|
session_id=get_value(driver.get_cookie("SimpleSAMLSessionID")),
|
|
session_ci=get_value(driver.get_cookie("session_ci")),
|
|
)
|
|
|
|
driver.close()
|
|
|
|
|
|
def get_course_clip_ids(course_id: str) -> list[str]:
|
|
global _token
|
|
|
|
regex = re.compile(r'(/clip/id/)([0-9]+)(\"\s*class=\"preview\")')
|
|
|
|
urls = []
|
|
|
|
url = f'https://www.fau.tv/course/id/{course_id}'
|
|
with requests.get(url, cookies=_cookies()) as r:
|
|
clip_matches = regex.findall(r.text)
|
|
for match in clip_matches:
|
|
urls.append(match[1])
|
|
|
|
return urls
|
|
|
|
|
|
def get_clip_details(clip_id: str) -> ClipDetails:
|
|
global _token
|
|
|
|
url = f'https://www.fau.tv/clip/id/{clip_id}'
|
|
details = ClipDetails(clip_id=clip_id)
|
|
|
|
with requests.get(url, cookies=_cookies()) as r:
|
|
def get_details(keyword: str):
|
|
mediaid_re = re.compile(
|
|
r'(' + keyword + r'Sources[^,]*,\s+mediaid\:\s+\")([0-9]+)'
|
|
)
|
|
|
|
playlist_url_re = re.compile(
|
|
r'(file\:\s+\")([^\"]*' + keyword + r'\.smil[^\"]*)(\")'
|
|
)
|
|
|
|
mediaid_matches = mediaid_re.findall(r.text)
|
|
if len(mediaid_matches) > 0:
|
|
setattr(details, keyword + "_media_id", mediaid_matches[0][1])
|
|
|
|
playlist_url_matches = playlist_url_re.findall(r.text)
|
|
if len(playlist_url_matches) > 0:
|
|
setattr(details, keyword + "_playlist_url",
|
|
playlist_url_matches[0][1])
|
|
|
|
get_details("combined")
|
|
get_details("camera")
|
|
get_details("slides")
|
|
|
|
return details
|
|
|
|
|
|
def download_media(media_id: str, outfile_path: str):
|
|
global _token
|
|
|
|
url = f'https://itunes.video.uni-erlangen.de/get/file/' + \
|
|
str(media_id) + '?download=1'
|
|
|
|
cookie_args = []
|
|
if len(_cookies()) > 0:
|
|
for key, value in _cookies().items():
|
|
cookie_args.append('--cookie')
|
|
cookie_args.append(f'{key}={value}')
|
|
|
|
status = subprocess.call(
|
|
['curl', '-f', '-o', outfile_path, url] + cookie_args)
|
|
return status == 0
|
|
|
|
|
|
def download_playlist(playlist_url: str, outfile_path: str):
|
|
subprocess.call([
|
|
'ffmpeg',
|
|
'-i', playlist_url,
|
|
'-c', 'copy',
|
|
outfile_path,
|
|
])
|
|
|
|
|
|
def download_clip(clip_id: str, outfile_path: str):
|
|
details = get_clip_details(clip_id)
|
|
|
|
if len(details.media_ids()) > 0:
|
|
media_id = details.media_ids()[0]
|
|
print(f"Trying to download clip {clip_id} using media id {media_id}")
|
|
if download_media(media_id, outfile_path):
|
|
return
|
|
|
|
if len(details.playlist_urls()) > 0:
|
|
playlist_url = details.playlist_urls()[0]
|
|
print(
|
|
f"Trying to download clip {clip_id} using playlist url {playlist_url}")
|
|
download_playlist(playlist_url, outfile_path)
|