mirror of
https://github.com/Garmelon/PFERD.git
synced 2023-12-21 10:23:01 +01:00
b2a2b5999b
This commit introduces the necessary machinery to authenticate with ILIAS and crawl the home page. It can't do much yet and just silently fetches the homepage.
57 lines
1.5 KiB
Python
57 lines
1.5 KiB
Python
import asyncio
|
|
import contextvars
|
|
import functools
|
|
import getpass
|
|
from typing import Any, Callable, Optional, TypeVar
|
|
|
|
import bs4
|
|
|
|
T = TypeVar("T")
|
|
|
|
|
|
# TODO When switching to 3.9, use asyncio.to_thread instead of this
|
|
async def to_thread(func: Callable[..., T], *args: Any, **kwargs: Any) -> T:
|
|
# https://github.com/python/cpython/blob/8d47f92d46a92a5931b8f3dcb4a484df672fc4de/Lib/asyncio/threads.py
|
|
loop = asyncio.get_event_loop()
|
|
ctx = contextvars.copy_context()
|
|
func_call = functools.partial(ctx.run, func, *args, **kwargs)
|
|
return await loop.run_in_executor(None, func_call) # type: ignore
|
|
|
|
|
|
async def ainput(prompt: str) -> str:
|
|
return await to_thread(lambda: input(prompt))
|
|
|
|
|
|
async def agetpass(prompt: str) -> str:
|
|
return await to_thread(lambda: getpass.getpass(prompt))
|
|
|
|
def soupify(data: bytes) -> bs4.BeautifulSoup:
|
|
"""
|
|
Parses HTML to a beautifulsoup object.
|
|
"""
|
|
|
|
return bs4.BeautifulSoup(data, "html.parser")
|
|
|
|
async def prompt_yes_no(query: str, default: Optional[bool]) -> bool:
|
|
"""
|
|
Asks the user a yes/no question and returns their choice.
|
|
"""
|
|
|
|
if default is True:
|
|
query += " [Y/n] "
|
|
elif default is False:
|
|
query += " [y/N] "
|
|
else:
|
|
query += " [y/n] "
|
|
|
|
while True:
|
|
response = (await ainput(query)).strip().lower()
|
|
if response == "y":
|
|
return True
|
|
elif response == "n":
|
|
return False
|
|
elif response == "" and default is not None:
|
|
return default
|
|
|
|
print("Please answer with 'y' or 'n'.")
|