Coverage for slidge/util/types.py: 99%
97 statements
« prev ^ index » next coverage.py v7.6.1, created at 2024-11-07 05:11 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2024-11-07 05:11 +0000
1"""
2Typing stuff
3"""
5from dataclasses import dataclass
6from datetime import datetime
7from enum import IntEnum
8from pathlib import Path
9from typing import (
10 IO,
11 TYPE_CHECKING,
12 Any,
13 Generic,
14 Hashable,
15 Literal,
16 NamedTuple,
17 Optional,
18 TypedDict,
19 TypeVar,
20 Union,
21)
23from slixmpp import Message, Presence
24from slixmpp.types import PresenceShows, PresenceTypes
26if TYPE_CHECKING:
27 from ..contact import LegacyContact
28 from ..core.pubsub import PepItem
29 from ..core.session import BaseSession
30 from ..group.participant import LegacyMUC, LegacyParticipant
32 AnyBaseSession = BaseSession[Any, Any]
33else:
34 AnyBaseSession = None
37class URL(str):
38 pass
41LegacyGroupIdType = TypeVar("LegacyGroupIdType", bound=Hashable)
42"""
43Type of the unique identifier for groups, usually a str or an int,
44but anything hashable should work.
45"""
46LegacyMessageType = TypeVar("LegacyMessageType", bound=Hashable)
47LegacyThreadType = TypeVar("LegacyThreadType", bound=Hashable)
48LegacyUserIdType = TypeVar("LegacyUserIdType", bound=Hashable)
50LegacyContactType = TypeVar("LegacyContactType", bound="LegacyContact")
51LegacyMUCType = TypeVar("LegacyMUCType", bound="LegacyMUC")
52LegacyParticipantType = TypeVar("LegacyParticipantType", bound="LegacyParticipant")
54PepItemType = TypeVar("PepItemType", bound="PepItem")
56Recipient = Union["LegacyMUC", "LegacyContact"]
57RecipientType = TypeVar("RecipientType", bound=Recipient)
58Sender = Union["LegacyContact", "LegacyParticipant"]
59AvatarType = Union[bytes, str, Path]
60LegacyFileIdType = Union[int, str]
61AvatarIdType = Union[LegacyFileIdType, URL]
63ChatState = Literal["active", "composing", "gone", "inactive", "paused"]
64ProcessingHint = Literal["no-store", "markable", "store"]
65Marker = Literal["acknowledged", "received", "displayed"]
66FieldType = Literal[
67 "boolean",
68 "fixed",
69 "text-single",
70 "jid-single",
71 "jid-multi",
72 "list-single",
73 "list-multi",
74 "text-private",
75]
76MucAffiliation = Literal["owner", "admin", "member", "outcast", "none"]
77MucRole = Literal["visitor", "participant", "moderator", "none"]
78# https://xmpp.org/registrar/disco-categories.html#client
79ClientType = Literal[
80 "bot", "console", "game", "handheld", "pc", "phone", "sms", "tablet", "web"
81]
84@dataclass
85class MessageReference(Generic[LegacyMessageType]):
86 """
87 A "message reply", ie a "quoted message" (:xep:`0461`)
89 At the very minimum, the legacy message ID attribute must be set, but to
90 ensure that the quote is displayed in all XMPP clients, the author must also
91 be set (use the string "user" if the slidge user is the author of the referenced
92 message).
93 The body is used as a fallback for XMPP clients that do not support :xep:`0461`
94 of that failed to find the referenced message.
95 """
97 legacy_id: LegacyMessageType
98 author: Optional[Union[Literal["user"], "LegacyParticipant", "LegacyContact"]] = (
99 None
100 )
101 body: Optional[str] = None
104@dataclass
105class LegacyAttachment:
106 """
107 A file attachment to a message
109 At the minimum, one of the ``path``, ``steam``, ``data`` or ``url`` attribute
110 has to be set
112 To be used with :meth:`.LegacyContact.send_files` or
113 :meth:`.LegacyParticipant.send_files`
114 """
116 path: Optional[Union[Path, str]] = None
117 name: Optional[Union[str]] = None
118 stream: Optional[IO[bytes]] = None
119 data: Optional[bytes] = None
120 content_type: Optional[str] = None
121 legacy_file_id: Optional[Union[str, int]] = None
122 url: Optional[str] = None
123 caption: Optional[str] = None
124 """
125 A caption for this specific image. For a global caption for a list of attachments,
126 use the ``body`` parameter of :meth:`.AttachmentMixin.send_files`
127 """
129 def __post_init__(self):
130 if not any(
131 x is not None for x in (self.path, self.stream, self.data, self.url)
132 ):
133 raise TypeError("There is not data in this attachment", self)
136class MucType(IntEnum):
137 """
138 The type of group, private, public, anonymous or not.
139 """
141 GROUP = 0
142 """
143 A private group, members-only and non-anonymous, eg a family group.
144 """
145 CHANNEL = 1
146 """
147 A public group, aka an anonymous channel.
148 """
149 CHANNEL_NON_ANONYMOUS = 2
150 """
151 A public group where participants' legacy IDs are visible to everybody.
152 """
155PseudoPresenceShow = Union[PresenceShows, Literal[""]]
158class ResourceDict(TypedDict):
159 show: PseudoPresenceShow
160 status: str
161 priority: int
164MessageOrPresenceTypeVar = TypeVar(
165 "MessageOrPresenceTypeVar", bound=Union[Message, Presence]
166)
169class LinkPreview(NamedTuple):
170 about: str
171 title: Optional[str]
172 description: Optional[str]
173 url: Optional[str]
174 image: Optional[str]
175 type: Optional[str]
176 site_name: Optional[str]
179class Mention(NamedTuple):
180 contact: "LegacyContact"
181 start: int
182 end: int
185class Hat(NamedTuple):
186 uri: str
187 title: str
190class UserPreferences(TypedDict):
191 sync_avatar: bool
192 sync_presence: bool
195class MamMetadata(NamedTuple):
196 id: str
197 sent_on: datetime
200class HoleBound(NamedTuple):
201 id: int | str
202 timestamp: datetime
205class CachedPresence(NamedTuple):
206 last_seen: Optional[datetime] = None
207 ptype: Optional[PresenceTypes] = None
208 pstatus: Optional[str] = None
209 pshow: Optional[PresenceShows] = None
212class Sticker(NamedTuple):
213 path: Path
214 content_type: Optional[str]
215 hashes: dict[str, str]