# /// script # dependencies = [ # "requests", # "beautifulsoup4", # "pypdf", # ] # /// import io from collections.abc import Iterable from functools import partial from getpass import getpass from pathlib import Path import pypdf import requests from bs4 import BeautifulSoup def get_token(s: requests.Session | None): get_token = (s or requests).get("https://moodle.usth.edu.vn/login/index.php") n = BeautifulSoup(get_token.content, features="lxml").select_one( "form[action='https://moodle.usth.edu.vn/login/index.php'] input[name=logintoken]" ) return n and n.get("value") def merge_pdfs(pdfs: Iterable[bytes]) -> bytes: merger = pypdf.PdfWriter() for f in pdfs: with io.BytesIO(f) as s: merger.append(s) with io.BytesIO() as f: merger.write(f) return f.getvalue() def real(s: requests.Session, usrname: str, passwd: str) -> bool: c = s.post( "https://moodle.usth.edu.vn/login/index.php", data={ "username": usrname, "password": passwd, # "rememberusername": 1, "anchor": "", "logintoken": get_token(s), }, ).content return ( BeautifulSoup(c, features="lxml").select_one("a#loginerrormessage") is not None ) def ts_pdf(s: requests.Session, url: str) -> bytes: u = s.get(url, stream=True) u.raise_for_status() if not u.content: raise ValueError(f"{url}: what the fuck") if u.headers.get("Content-Type") != "application/pdf": raise ValueError(f"{url}: content type: {u.headers.get('Content-Type')}") data = b"".join(u.iter_content(8192)) if not data.startswith(b"%PDF"): raise ValueError(f"{url}: Not a PDF") if b"%%EOF" not in data[-1024:]: raise ValueError(f"{url}: PDF looks truncated") return data def main(): u, p = input("Username: "), getpass("Password: ") pdfs = ( # example "https://moodle.usth.edu.vn/pluginfile.php/91136/mod_resource/content/1/Chapter%201%20v1.pdf", "https://moodle.usth.edu.vn/pluginfile.php/91137/mod_resource/content/1/Chapter%202.pdf", "https://moodle.usth.edu.vn/pluginfile.php/91138/mod_resource/content/1/Chapter%203%20%20.pdf", "https://moodle.usth.edu.vn/pluginfile.php/91964/mod_resource/content/1/Chapter%204%20%5BAutosaved%5D.pdf", "https://moodle.usth.edu.vn/pluginfile.php/91965/mod_resource/content/1/Chapter%206.pdf", "https://moodle.usth.edu.vn/pluginfile.php/92412/mod_resource/content/1/Chapter%209.pdf", ) with requests.Session() as s: real(s, u, p) ppdf = partial(ts_pdf, s) b = map(ppdf, pdfs) Path("merged_.pdf").write_bytes(merge_pdfs(b)) print("write done to merged_.pdf") if __name__ == "__main__": main()