-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathutils.py
More file actions
34 lines (26 loc) · 1.17 KB
/
Copy pathutils.py
File metadata and controls
34 lines (26 loc) · 1.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
from __future__ import annotations
import base64
import json
from datetime import UTC, datetime
APPLE_EPOCH_OFFSET = 978307200
def coredata_to_datetime(value: float | int | None) -> datetime | None:
"""Convert a Core Data timestamp into a UTC datetime."""
if value is None:
return None
return datetime.fromtimestamp(float(value) + APPLE_EPOCH_OFFSET, tz=UTC)
def encode_cursor(message_date: float, message_id: int) -> str:
"""Encode a message pagination cursor into URL-safe text."""
payload = {"d": float(message_date), "i": int(message_id)}
raw = json.dumps(payload, separators=(",", ":")).encode("utf-8")
return base64.urlsafe_b64encode(raw).decode("ascii").rstrip("=")
def decode_cursor(cursor: str | None) -> tuple[float, int] | None:
"""Decode a pagination cursor into `(message_date, message_id)`."""
if not cursor:
return None
padding = "=" * (-len(cursor) % 4)
try:
decoded = base64.urlsafe_b64decode(cursor + padding).decode("utf-8")
payload = json.loads(decoded)
return float(payload["d"]), int(payload["i"])
except KeyError, TypeError, ValueError, json.JSONDecodeError:
return None