Module librusapi.messages
Expand source code
from dataclasses import dataclass
from datetime import datetime
from librusapi.token import Token
from typing import Iterator, Optional, Tuple
from requests.sessions import Session, Request
from librusapi.urls import MESSAGES_URL
from librusapi.helpers import sanitize
from bs4 import BeautifulSoup
import re
@dataclass
class MessageBrief:
"""A quick briefing of a message.
Has necessary information to retrieve the full message.
Attributes:
id: message id
title: message title
sender: sender alias and full name between brackets
e.g. admin (John Doe)
sent: when was the message sent
has_attachment: whether message contains an attachment
is_read: whether message was read or not
"""
id: str
title: str
sender: str
sent: datetime
has_attachment: bool
is_read: bool
def _message_list_get_html(token: Token, page: int) -> str:
payload = {
"filtrUzytkownikow": 0,
"idPojemnika": 105,
"opcja_zaznaczone_g": 0,
"filtr_uzytkownikow": "-",
"sortujTabele[tabeleKolumna]": 3,
"sortujTabele[tabeleKierunek]": 1,
"sortujTabele[tabelePojemnik]": 105,
"sortowanie[105][0]": "",
"sortowanie[105][1]": "",
"sortowanie[105][2]": "",
"opcja_zaznaczone_d": 0,
"numer_strony105": page,
"porcjowanie_pojemnik105": 105,
"poprzednia": 5,
}
# Don't send file="$NAME" field
for k, v in payload.items():
payload[k] = (None, v)
resp = token.post(MESSAGES_URL, files=payload)
return resp.text
@dataclass
class PageInfo:
"""Stores page related information for paginated requests"""
current: int
max_page: int
def _parse_message_page_info(doc: BeautifulSoup) -> PageInfo:
elem = doc.find("div", class_="pagination").find("span")
pagination_desc = sanitize(elem.text)
match = re.findall("[0-9][^ ]*", pagination_desc)
current = int(match[0]) - 1
max_page = int(match[1]) - 1
return PageInfo(current, max_page)
def _parse_message_briefs(doc: BeautifulSoup) -> Iterator[MessageBrief]:
table = doc.find("table", class_="decorated stretch").find("tbody")
trs = table.find_all("tr")
for tr in trs:
links = tr.find_all("a")
inp = tr.find("input")
id = inp.attrs.get("value")
sender_elem = links[0]
is_read = "style" not in sender_elem.parent.attrs
has_attachment = tr.find("img") is not None
sender = sanitize(sender_elem.text)
title = sanitize(links[1].text)
date_str = sanitize(tr.find("td", class_="medium center").text)
sent = datetime.strptime(date_str, "%Y-%m-%d %H:%M:%S")
yield MessageBrief(id, title, sender, sent, has_attachment, is_read)
def list_messages(token: Token, page: int) -> Tuple[PageInfo, Iterator[MessageBrief]]:
"""Generator for `MessageBrief`
Retrieves HTML and then parses it using Beautifulsoup.
Args:
token: Librus token.
Can be retrieved from `librusapi.token.get_token`.
page: Which page to retrieve
Returns:
`PageInfo` and Generator of `MessageBrief`
Raises:
requests.exceptions.HTTPError: When an error that is
unrelated to authenticaiton occurs.
AuthorizationError: When authorization using the token fails.
IndexError: When page is out of bounds
Example:
>>> messages = list_messages(token)
>>> for msg in messages:
... print(msg.id, msg.title, msg.sender, msg.sent, msg.has_attachment, msg.is_read sep='\\n')
... break
12345678
Welcome to the school system!
John Smith
2021-01-11 08:00:00
False
False
"""
html = _message_list_get_html(token, page)
doc = BeautifulSoup(html, features="lxml")
info = _parse_message_page_info(doc)
if info.current != page:
raise IndexError(f"Page doesn't exist! Max page: {info.max_page}")
msgs = _parse_message_briefs(doc)
return info, msgs
Functions
def list_messages(token: Token, page: int) ‑> Tuple[PageInfo, Iterator[MessageBrief]]
-
Generator for
MessageBrief
Retrieves HTML and then parses it using Beautifulsoup.
Args
token
- Librus token.
Can be retrieved from
get_token()
. page
- Which page to retrieve
Returns
PageInfo
and Generator ofMessageBrief
Raises
requests.exceptions.HTTPError
- When an error that is unrelated to authenticaiton occurs.
AuthorizationError
- When authorization using the token fails.
IndexError
- When page is out of bounds
Example:
>>> messages = list_messages(token) >>> for msg in messages: ... print(msg.id, msg.title, msg.sender, msg.sent, msg.has_attachment, msg.is_read sep='\n') ... break 12345678 Welcome to the school system! John Smith 2021-01-11 08:00:00 False False
Expand source code
def list_messages(token: Token, page: int) -> Tuple[PageInfo, Iterator[MessageBrief]]: """Generator for `MessageBrief` Retrieves HTML and then parses it using Beautifulsoup. Args: token: Librus token. Can be retrieved from `librusapi.token.get_token`. page: Which page to retrieve Returns: `PageInfo` and Generator of `MessageBrief` Raises: requests.exceptions.HTTPError: When an error that is unrelated to authenticaiton occurs. AuthorizationError: When authorization using the token fails. IndexError: When page is out of bounds Example: >>> messages = list_messages(token) >>> for msg in messages: ... print(msg.id, msg.title, msg.sender, msg.sent, msg.has_attachment, msg.is_read sep='\\n') ... break 12345678 Welcome to the school system! John Smith 2021-01-11 08:00:00 False False """ html = _message_list_get_html(token, page) doc = BeautifulSoup(html, features="lxml") info = _parse_message_page_info(doc) if info.current != page: raise IndexError(f"Page doesn't exist! Max page: {info.max_page}") msgs = _parse_message_briefs(doc) return info, msgs
Classes
class MessageBrief (id: str, title: str, sender: str, sent: datetime.datetime, has_attachment: bool, is_read: bool)
-
A quick briefing of a message.
Has necessary information to retrieve the full message.
Attributes
id
- message id
title
- message title
sender
- sender alias and full name between brackets e.g. admin (John Doe)
sent
- when was the message sent
has_attachment
- whether message contains an attachment
is_read
- whether message was read or not
Expand source code
@dataclass class MessageBrief: """A quick briefing of a message. Has necessary information to retrieve the full message. Attributes: id: message id title: message title sender: sender alias and full name between brackets e.g. admin (John Doe) sent: when was the message sent has_attachment: whether message contains an attachment is_read: whether message was read or not """ id: str title: str sender: str sent: datetime has_attachment: bool is_read: bool
Class variables
var has_attachment : bool
var id : str
var is_read : bool
var sender : str
var sent : datetime.datetime
var title : str
class PageInfo (current: int, max_page: int)
-
Stores page related information for paginated requests
Expand source code
@dataclass class PageInfo: """Stores page related information for paginated requests""" current: int max_page: int
Class variables
var current : int
var max_page : int