some small improvements

This commit is contained in:
Ludwig Lehnert 2024-07-11 23:11:00 +02:00
parent e49c4950e8
commit a20b0b27a8
3 changed files with 81 additions and 36 deletions

View File

@ -6,9 +6,22 @@ This software is provided without warranty. Usage is discouraged! Usage of this
## Usage ## Usage
```bash ```bash
./dl '<fau course id>' '[output directory]' '[starter url]' usage: dl [-h] [--outDir OUTDIR] [--starterUrl STARTERURL]
[--startAt STARTAT]
courseId
Download clips from a course
positional arguments:
courseId Course ID
options:
-h, --help show this help message and exit
--outDir OUTDIR Output directory
--starterUrl STARTERURL Starter URL
--startAt STARTAT Skip all previous indizes (starts at 1)
``` ```
# Procedure ## Procedure
Upon starting, a firefox instance is opened, prompting you to log in using IDM SSO. As soon as the url changes to something starting with `https://www.fau.tv`, download will be starting. If you do not want to provide your credentials, you can provide `https://www.fau.tv` as a starter url. Upon starting, a firefox instance is opened, prompting you to log in using IDM SSO. As soon as the url changes to something starting with `https://www.fau.tv`, download will be starting. If you do not want to provide your credentials, you can provide `https://www.fau.tv` as a starter url.

35
dl
View File

@ -1,21 +1,38 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from .lib import * from lib import *
import sys import sys
import os import os
import argparse
def parse_args():
parser = argparse.ArgumentParser(
description='Download clips from a course',
)
parser.add_argument('courseId', type=str, help='Course ID')
parser.add_argument('--outDir', type=str,
help='Output directory', default='./out')
parser.add_argument('--starterUrl', type=str,
help='Starter URL', default="https://www.fau.tv/auth/sso")
parser.add_argument('--startAt', type=int,
help='Skip all previous indizes (starts at 1)', default=1)
return parser.parse_args()
def main(): def main():
course_id = sys.argv[1] args = parse_args()
out_dir = sys.argv[2] if len(sys.argv) >= 3 else './out'
auth_url = sys.argv[3] if len(sys.argv) >= 4 else None
load_token(auth_url) if auth_url is not None else load_token() load_token(args.starterUrl)
os.makedirs(out_dir, exist_ok=True) os.makedirs(args.outDir, exist_ok=True)
for index, clip_id in enumerate(get_course_clip_ids(course_id)): for index, clip_id in enumerate(get_course_clip_ids(args.courseId)):
print(f'downloading clip {clip_id}') if index < args.startAt - 1:
download_clip(clip_id, f'{out_dir}/{index+1: 04d}_{clip_id}.mp4') continue
download_clip(clip_id, f'{args.outDir}/{index+1: 04d}_{clip_id}.mp4')
if __name__ == '__main__': if __name__ == '__main__':

61
lib.py
View File

@ -17,15 +17,24 @@ class Token():
session_ci: str session_ci: str
def cookies(self): def cookies(self):
return { cookies = {}
"SimpleSAMLAuthToken": self.auth_token,
"SimpleSAMLSessionID": self.session_id, if self.auth_token is not None:
"session_ci": self.session_ci, 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 @dataclass
class ClipDetails(): class ClipDetails():
clip_id: str
combined_media_id: str = None combined_media_id: str = None
combined_playlist_url: str = None combined_playlist_url: str = None
camera_media_id: str = None camera_media_id: str = None
@ -33,8 +42,22 @@ class ClipDetails():
slides_media_id: str = None slides_media_id: str = None
slides_playlist_url: 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 load_token(auth_url: str = "https://www.fau.tv/auth/sso"): 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 load_token(auth_url: str):
global _token global _token
driver = webdriver.Firefox() driver = webdriver.Firefox()
@ -55,8 +78,6 @@ def load_token(auth_url: str = "https://www.fau.tv/auth/sso"):
session_ci=get_value(driver.get_cookie("session_ci")), session_ci=get_value(driver.get_cookie("session_ci")),
) )
print(_token)
driver.close() driver.close()
@ -80,7 +101,7 @@ def get_clip_details(clip_id: str) -> ClipDetails:
global _token global _token
url = f'https://www.fau.tv/clip/id/{clip_id}' url = f'https://www.fau.tv/clip/id/{clip_id}'
details = ClipDetails() details = ClipDetails(clip_id=clip_id)
with requests.get(url, cookies=_token.cookies()) as r: with requests.get(url, cookies=_token.cookies()) as r:
def get_details(keyword: str): def get_details(keyword: str):
@ -130,25 +151,19 @@ def download_playlist(playlist_url: str, outfile_path: str):
'-i', playlist_url, '-i', playlist_url,
'-c', 'copy', '-c', 'copy',
outfile_path, outfile_path,
]) ], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
def download_clip(clip_id: str, outfile_path: str): def download_clip(clip_id: str, outfile_path: str):
details = get_clip_details(clip_id) details = get_clip_details(clip_id)
media_id = next(id for id in [ if len(details.media_ids()) > 0:
details.combined_media_id, media_id = details.media_ids()[0]
details.camera_media_id, print(f"Trying to download clip {clip_id} using media id {media_id}")
details.slides_media_id,
] if id is not None)
if download_media(media_id, outfile_path): if download_media(media_id, outfile_path):
return return
url = next(url for url in [ if len(details.playlist_urls()) > 0:
details.combined_playlist_url, playlist_url = details.playlist_urls()[0]
details.camera_playlist_url, print(f"Trying to download clip {clip_id} using playlist url {playlist_url}")
details.slides_playlist_url, download_playlist(playlist_url, outfile_path)
] if url is not None)
download_playlist(url, outfile_path)