librus-python-api 1.4.0__py3-none-any.whl → 1.5.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -136,7 +136,7 @@ from librus_python_api.models import (
136
136
  from librus_python_api.sending import SendAttempt
137
137
  from librus_python_api.service import AccountClient, LibrusService
138
138
 
139
- __version__ = "1.4.0"
139
+ __version__ = "1.5.0"
140
140
 
141
141
  __all__ = [
142
142
  "ArchiveAbsences",
@@ -57,26 +57,33 @@ def _recipient_receipts(
57
57
  raise LibrusError(ErrorKind.UNSUPPORTED_CAPABILITY)
58
58
  result = []
59
59
  total = 0
60
+ # Rows are recipient/status, or recipient/class/status when the page adds
61
+ # the class-label column; one table never mixes the two.
62
+ width = len(cells(table_rows[1]))
60
63
  for row in table_rows[1:]:
61
64
  columns = cells(row)
62
- if len(columns) != 2 or any(
63
- c.tag != "td"
64
- or c.get("colspan", "1") != "1"
65
- or c.get("rowspan", "1") != "1"
66
- or next(c.iterdescendants("table"), None) is not None
67
- for c in columns
65
+ if (
66
+ len(columns) != width
67
+ or width not in (2, 3)
68
+ or any(
69
+ c.tag != "td"
70
+ or c.get("colspan", "1") != "1"
71
+ or c.get("rowspan", "1") != "1"
72
+ or next(c.iterdescendants("table"), None) is not None
73
+ for c in columns
74
+ )
68
75
  ):
69
76
  raise LibrusError(ErrorKind.UNSUPPORTED_CAPABILITY)
70
- recipient, status = [
71
- text(c, MESSAGE_MAX_FIELD_LENGTH, multiline=True) for c in columns
72
- ]
77
+ values = [text(c, MESSAGE_MAX_FIELD_LENGTH, multiline=True) for c in columns]
78
+ recipient, status = values[0], values[-1]
73
79
  if not recipient or not status:
74
80
  raise LibrusError(ErrorKind.PARSE)
75
- total += len(recipient) + len(status)
81
+ total += sum(map(len, values))
76
82
  if total > MESSAGE_MAX_RECEIPT_TEXT_LENGTH:
77
83
  raise LibrusError(ErrorKind.LIMIT)
78
84
  stamp = None if status == "NIE" else _timestamp(status)
79
- result.append(MessageRecipientReceipt(recipient, status, stamp))
85
+ label = values[1] if width == 3 and values[1] else None
86
+ result.append(MessageRecipientReceipt(recipient, status, stamp, label))
80
87
  return tuple(result)
81
88
 
82
89
 
@@ -210,6 +210,8 @@ class MessageRecipientReceipt:
210
210
  recipient: str = field(repr=False)
211
211
  raw_status: str = field(repr=False)
212
212
  read_timestamp: MessageTimestamp | None = field(repr=False)
213
+ # Displayed class label of the optional middle column; None without it.
214
+ recipient_class: str | None = field(default=None, repr=False)
213
215
 
214
216
 
215
217
  @dataclass(frozen=True, slots=True)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: librus-python-api
3
- Version: 1.4.0
3
+ Version: 1.5.0
4
4
  Summary: Independent bounded async Librus Synergia client
5
5
  Project-URL: Repository, https://github.com/krzysztofbury/librus-python-api
6
6
  Project-URL: Issues, https://github.com/krzysztofbury/librus-python-api/issues
@@ -42,9 +42,9 @@ private ACLs. Windows installations include `pywin32` and `tzdata` automatically
42
42
  Network paths, reparse-point paths and unsafe storage permissions fail closed.
43
43
  See [platform requirements](contracts/persistence.md#windows-disk-boundary-25).
44
44
 
45
- **Status:** `1.4.0` adds formative assessments, including the observation card,
46
- to grade results. The 1.3.0 archive read passed installed live checks for
47
- populated and empty archives on two parent logins; see [verification](VERIFICATION.md).
45
+ **Status:** `1.5.0` reads sent-message receipt tables that show a recipient
46
+ class column. `1.4.0` added formative assessments, including the observation
47
+ card, to grade results; see [verification](VERIFICATION.md).
48
48
  The stable 1.x API does not guarantee every school layout. School features depend
49
49
  on what each account can access. See the [compatibility policy](API.md#compatibility-policy).
50
50
  See [limitations](#supported-features-and-limitations) below.
@@ -54,7 +54,7 @@ See [limitations](#supported-features-and-limitations) below.
54
54
  Install the exact release from PyPI after its gated publication completes:
55
55
 
56
56
  ```sh
57
- python -m pip install librus-python-api==1.4.0
57
+ python -m pip install librus-python-api==1.5.0
58
58
  ```
59
59
 
60
60
  Pin the exact version qualified by your application. Before publication, use a
@@ -70,7 +70,7 @@ python -m pip install .
70
70
  To install a locally built wheel instead:
71
71
 
72
72
  ```sh
73
- python -m pip install ./dist/librus_python_api-1.4.0-py3-none-any.whl
73
+ python -m pip install ./dist/librus_python_api-1.5.0-py3-none-any.whl
74
74
  ```
75
75
 
76
76
  No CLI or background process is installed: import the library in your own program.
@@ -1,4 +1,4 @@
1
- librus_python_api/__init__.py,sha256=Ka6_hAV-fnh3QrjAPyqhWPvaG2eh5w8VT8a5aB_RBNU,6435
1
+ librus_python_api/__init__.py,sha256=I1Qf4LlyITCJWMgO6Ce4Ujf7EP8VmHXitvRk07kKCVw,6435
2
2
  librus_python_api/_notification_bootstrap.py,sha256=18nzH0doXBNaZXCz-_ckIvRrlHTWV5Mm1t5m2-5eYGI,4669
3
3
  librus_python_api/_notification_codec.py,sha256=hU6G3zGJ5fR8wfPC6fV2OqBKs-7XpT9eRnKO3FGsTzY,13451
4
4
  librus_python_api/_storage.py,sha256=M_6ZAzN4zs7laOdKJBRH1I2rvy3pgqYgC_MZtsd2xtM,15893
@@ -22,9 +22,9 @@ librus_python_api/grade_records.py,sha256=K0ZzmU1KsA8Jo1MXh30mStApgrigaOKk5ldoBn
22
22
  librus_python_api/homework_range.py,sha256=erYfvS6PhHU5XhnR6LkiLNy677hGVflY3UAuHOs-YUw,1663
23
23
  librus_python_api/lifecycle.py,sha256=XzA5CEdZFo7iL5IMUrawnRvf2m9BFe0OseP-fpQFaAE,856
24
24
  librus_python_api/markup.py,sha256=mjCZf6KJTWUz2vjfXbJ4zM17hnev7a5AFIOW3ip3gsE,5677
25
- librus_python_api/message_content.py,sha256=sUPuqpjuavqDyn6QGM5aPH4mpoQV62bDLepSSQ2AsUE,8686
25
+ librus_python_api/message_content.py,sha256=v_qoEAoaYS0_9MQBaj57i5XnC7pzv_HHWefgTt4CNyM,9043
26
26
  librus_python_api/messages.py,sha256=K9F8XVs1SojfFpdxxLV8gx9E0g81YxEHjigDzLHmDCg,10230
27
- librus_python_api/models.py,sha256=wWMw2TXmeRWP3yJLSDmdVDYsbXRIztm3mEhCYPH1gco,40310
27
+ librus_python_api/models.py,sha256=Mv7V2dg96aw41zO8flpOBLOnaNWETr4IJMxRa-RMxDk,40452
28
28
  librus_python_api/modern_body.py,sha256=3L4P_cIrHdIxZqiinFSQrDMhG6iklT1GoA-VEWMJUiI,2682
29
29
  librus_python_api/modern_mailbox.py,sha256=2jF9UnJZ5AF6dip-GrMcv_z2kSLpp87dIpVeXk9jMzA,20600
30
30
  librus_python_api/modern_messages.py,sha256=qt2CXtrxCZQ-jTt0aQCD6ZaPAJQZXf0BxmvacPo9B0w,10653
@@ -44,7 +44,7 @@ librus_python_api/sending.py,sha256=Nvvk2r-6D6Us53a2fH5GW9PcA6bWEfuOvy6c3M5QVcE,
44
44
  librus_python_api/service.py,sha256=yjdKc4-psMDlIHVLud-WA2YDXafKPuTT-hLdVmdWsIM,94464
45
45
  librus_python_api/timetable.py,sha256=tX1QK9fQABxzfLaHHqTe8e6rAgdOkCoTOfAHdPwNmLE,9836
46
46
  librus_python_api/transport.py,sha256=QnYXnrv1lW4qToYoTv6HyZw-Lt4rDc-_SMTJpMp6_bc,35297
47
- librus_python_api-1.4.0.dist-info/METADATA,sha256=VKqlisucgyKpgIO7aGudJPX8-gKpm5mB3ZEm_59jJzE,12031
48
- librus_python_api-1.4.0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
49
- librus_python_api-1.4.0.dist-info/licenses/LICENSE,sha256=IuerLb3cnZCsaB23znydjjvKqP-LmSJd3syKa9NGUts,1071
50
- librus_python_api-1.4.0.dist-info/RECORD,,
47
+ librus_python_api-1.5.0.dist-info/METADATA,sha256=vVhNXk_P3l95cfa2_dM5yabNZTBTf0FZL_M3VGHZrxU,12003
48
+ librus_python_api-1.5.0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
49
+ librus_python_api-1.5.0.dist-info/licenses/LICENSE,sha256=IuerLb3cnZCsaB23znydjjvKqP-LmSJd3syKa9NGUts,1071
50
+ librus_python_api-1.5.0.dist-info/RECORD,,