91 lines
2.8 KiB
Python
91 lines
2.8 KiB
Python
# /// 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()
|