Coverage for slidge/core/mixins/disco.py: 97%
87 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
1from typing import Optional
3from slixmpp.plugins.xep_0004 import Form
4from slixmpp.plugins.xep_0030.stanza.info import DiscoInfo
5from slixmpp.types import OptJid
7from .base import Base
10class BaseDiscoMixin(Base):
11 DISCO_TYPE: str = NotImplemented
12 DISCO_CATEGORY: str = NotImplemented
13 DISCO_NAME: str = NotImplemented
14 DISCO_LANG = None
16 def _get_disco_name(self):
17 if self.DISCO_NAME is NotImplemented:
18 return self.xmpp.COMPONENT_NAME
19 return self.DISCO_NAME or self.xmpp.COMPONENT_NAME
21 def features(self):
22 return []
24 async def extended_features(self) -> Optional[list[Form]]:
25 return None
27 async def get_disco_info(self, jid: OptJid = None, node: Optional[str] = None):
28 info = DiscoInfo()
29 for feature in self.features():
30 info.add_feature(feature)
31 info.add_identity(
32 category=self.DISCO_CATEGORY,
33 itype=self.DISCO_TYPE,
34 name=self._get_disco_name(),
35 lang=self.DISCO_LANG,
36 )
37 if forms := await self.extended_features():
38 for form in forms:
39 info.append(form)
40 return info
42 async def get_caps_ver(self, jid: OptJid = None, node: Optional[str] = None):
43 info = await self.get_disco_info(jid, node)
44 caps = self.xmpp.plugin["xep_0115"]
45 ver = caps.generate_verstring(info, caps.hash)
46 return ver
49class ChatterDiscoMixin(BaseDiscoMixin):
50 AVATAR = True
51 RECEIPTS = True
52 MARKS = True
53 CHAT_STATES = True
54 UPLOAD = True
55 CORRECTION = True
56 REACTION = True
57 RETRACTION = True
58 REPLIES = True
59 INVITATION_RECIPIENT = False
61 DISCO_TYPE = "pc"
62 DISCO_CATEGORY = "client"
63 DISCO_NAME = ""
65 def features(self):
66 features = []
67 if self.CHAT_STATES:
68 features.append("http://jabber.org/protocol/chatstates")
69 if self.RECEIPTS:
70 features.append("urn:xmpp:receipts")
71 if self.CORRECTION:
72 features.append("urn:xmpp:message-correct:0")
73 if self.MARKS:
74 features.append("urn:xmpp:chat-markers:0")
75 if self.UPLOAD:
76 features.append("jabber:x:oob")
77 if self.REACTION:
78 features.append("urn:xmpp:reactions:0")
79 if self.RETRACTION:
80 features.append("urn:xmpp:message-retract:0")
81 if self.REPLIES:
82 features.append("urn:xmpp:reply:0")
83 if self.INVITATION_RECIPIENT:
84 features.append("jabber:x:conference")
85 features.append("urn:ietf:params:xml:ns:vcard-4.0")
86 return features
88 async def extended_features(self):
89 f = getattr(self, "restricted_emoji_extended_feature", None)
90 if f is None:
91 return
93 e = await f()
94 if not e:
95 return
97 return [e]
100class ContactAccountDiscoMixin(BaseDiscoMixin):
101 async def get_disco_info(self, jid: OptJid = None, node: Optional[str] = None):
102 if jid and jid.resource:
103 return await super().get_disco_info()
104 info = DiscoInfo()
105 info.add_feature("http://jabber.org/protocol/pubsub")
106 info.add_feature("http://jabber.org/protocol/pubsub#retrieve-items")
107 info.add_feature("http://jabber.org/protocol/pubsub#subscribe")
108 info.add_identity(
109 category="account",
110 itype="registered",
111 name=self._get_disco_name(),
112 lang=self.DISCO_LANG,
113 )
114 info.add_identity(
115 category="pubsub",
116 itype="pep",
117 name=self._get_disco_name(),
118 lang=self.DISCO_LANG,
119 )
120 return info