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

1""" 

2Typing stuff 

3""" 

4 

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) 

22 

23from slixmpp import Message, Presence 

24from slixmpp.types import PresenceShows, PresenceTypes 

25 

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 

31 

32 AnyBaseSession = BaseSession[Any, Any] 

33else: 

34 AnyBaseSession = None 

35 

36 

37class URL(str): 

38 pass 

39 

40 

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) 

49 

50LegacyContactType = TypeVar("LegacyContactType", bound="LegacyContact") 

51LegacyMUCType = TypeVar("LegacyMUCType", bound="LegacyMUC") 

52LegacyParticipantType = TypeVar("LegacyParticipantType", bound="LegacyParticipant") 

53 

54PepItemType = TypeVar("PepItemType", bound="PepItem") 

55 

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] 

62 

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] 

82 

83 

84@dataclass 

85class MessageReference(Generic[LegacyMessageType]): 

86 """ 

87 A "message reply", ie a "quoted message" (:xep:`0461`) 

88 

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 """ 

96 

97 legacy_id: LegacyMessageType 

98 author: Optional[Union[Literal["user"], "LegacyParticipant", "LegacyContact"]] = ( 

99 None 

100 ) 

101 body: Optional[str] = None 

102 

103 

104@dataclass 

105class LegacyAttachment: 

106 """ 

107 A file attachment to a message 

108 

109 At the minimum, one of the ``path``, ``steam``, ``data`` or ``url`` attribute 

110 has to be set 

111 

112 To be used with :meth:`.LegacyContact.send_files` or 

113 :meth:`.LegacyParticipant.send_files` 

114 """ 

115 

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 """ 

128 

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) 

134 

135 

136class MucType(IntEnum): 

137 """ 

138 The type of group, private, public, anonymous or not. 

139 """ 

140 

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 """ 

153 

154 

155PseudoPresenceShow = Union[PresenceShows, Literal[""]] 

156 

157 

158class ResourceDict(TypedDict): 

159 show: PseudoPresenceShow 

160 status: str 

161 priority: int 

162 

163 

164MessageOrPresenceTypeVar = TypeVar( 

165 "MessageOrPresenceTypeVar", bound=Union[Message, Presence] 

166) 

167 

168 

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] 

177 

178 

179class Mention(NamedTuple): 

180 contact: "LegacyContact" 

181 start: int 

182 end: int 

183 

184 

185class Hat(NamedTuple): 

186 uri: str 

187 title: str 

188 

189 

190class UserPreferences(TypedDict): 

191 sync_avatar: bool 

192 sync_presence: bool 

193 

194 

195class MamMetadata(NamedTuple): 

196 id: str 

197 sent_on: datetime 

198 

199 

200class HoleBound(NamedTuple): 

201 id: int | str 

202 timestamp: datetime 

203 

204 

205class CachedPresence(NamedTuple): 

206 last_seen: Optional[datetime] = None 

207 ptype: Optional[PresenceTypes] = None 

208 pstatus: Optional[str] = None 

209 pshow: Optional[PresenceShows] = None 

210 

211 

212class Sticker(NamedTuple): 

213 path: Path 

214 content_type: Optional[str] 

215 hashes: dict[str, str]