comparison sat/plugins/plugin_xep_0084.py @ 4037:524856bd7b19

massive refactoring to switch from camelCase to snake_case: historically, Libervia (SàT before) was using camelCase as allowed by PEP8 when using a pre-PEP8 code, to use the same coding style as in Twisted. However, snake_case is more readable and it's better to follow PEP8 best practices, so it has been decided to move on full snake_case. Because Libervia has a huge codebase, this ended with a ugly mix of camelCase and snake_case. To fix that, this patch does a big refactoring by renaming every function and method (including bridge) that are not coming from Twisted or Wokkel, to use fully snake_case. This is a massive change, and may result in some bugs.
author Goffi <goffi@goffi.org>
date Sat, 08 Apr 2023 13:54:42 +0200
parents 88e332cec47b
children
comparison
equal deleted inserted replaced
4036:c4464d7ae97b 4037:524856bd7b19
59 namespace_metadata = NS_AVATAR_METADATA 59 namespace_metadata = NS_AVATAR_METADATA
60 namespace_data = NS_AVATAR_DATA 60 namespace_data = NS_AVATAR_DATA
61 61
62 def __init__(self, host): 62 def __init__(self, host):
63 log.info(_("XEP-0084 (User Avatar) plugin initialization")) 63 log.info(_("XEP-0084 (User Avatar) plugin initialization"))
64 host.registerNamespace("avatar_metadata", NS_AVATAR_METADATA) 64 host.register_namespace("avatar_metadata", NS_AVATAR_METADATA)
65 host.registerNamespace("avatar_data", NS_AVATAR_DATA) 65 host.register_namespace("avatar_data", NS_AVATAR_DATA)
66 self.host = host 66 self.host = host
67 self._p = host.plugins["XEP-0060"] 67 self._p = host.plugins["XEP-0060"]
68 self._i = host.plugins['IDENTITY'] 68 self._i = host.plugins['IDENTITY']
69 self._i.register( 69 self._i.register(
70 IMPORT_NAME, 70 IMPORT_NAME,
71 "avatar", 71 "avatar",
72 self.getAvatar, 72 self.get_avatar,
73 self.setAvatar, 73 self.set_avatar,
74 priority=2000 74 priority=2000
75 ) 75 )
76 host.plugins["XEP-0163"].addPEPEvent( 76 host.plugins["XEP-0163"].add_pep_event(
77 None, NS_AVATAR_METADATA, self._onMetadataUpdate 77 None, NS_AVATAR_METADATA, self._on_metadata_update
78 ) 78 )
79 79
80 def getHandler(self, client): 80 def get_handler(self, client):
81 return XEP_0084_Handler() 81 return XEP_0084_Handler()
82 82
83 def _onMetadataUpdate(self, itemsEvent, profile): 83 def _on_metadata_update(self, itemsEvent, profile):
84 client = self.host.getClient(profile) 84 client = self.host.get_client(profile)
85 defer.ensureDeferred(self.onMetadataUpdate(client, itemsEvent)) 85 defer.ensureDeferred(self.on_metadata_update(client, itemsEvent))
86 86
87 async def onMetadataUpdate( 87 async def on_metadata_update(
88 self, 88 self,
89 client: SatXMPPEntity, 89 client: SatXMPPEntity,
90 itemsEvent: pubsub.ItemsEvent 90 itemsEvent: pubsub.ItemsEvent
91 ) -> None: 91 ) -> None:
92 entity = client.jid.userhostJID() 92 entity = client.jid.userhostJID()
93 avatar_metadata = await self.getAvatar(client, entity) 93 avatar_metadata = await self.get_avatar(client, entity)
94 await self._i.update(client, IMPORT_NAME, "avatar", avatar_metadata, entity) 94 await self._i.update(client, IMPORT_NAME, "avatar", avatar_metadata, entity)
95 95
96 async def getAvatar( 96 async def get_avatar(
97 self, 97 self,
98 client: SatXMPPEntity, 98 client: SatXMPPEntity,
99 entity_jid: jid.JID 99 entity_jid: jid.JID
100 ) -> Optional[dict]: 100 ) -> Optional[dict]:
101 """Get avatar data 101 """Get avatar data
104 @return: avatar metadata, or None if no avatar has been found 104 @return: avatar metadata, or None if no avatar has been found
105 """ 105 """
106 service = entity_jid.userhostJID() 106 service = entity_jid.userhostJID()
107 # metadata 107 # metadata
108 try: 108 try:
109 items, __ = await self._p.getItems( 109 items, __ = await self._p.get_items(
110 client, 110 client,
111 service, 111 service,
112 NS_AVATAR_METADATA, 112 NS_AVATAR_METADATA,
113 max_items=1 113 max_items=1
114 ) 114 )
144 else: 144 else:
145 # mandatory image/png is missing, or avatar is disabled 145 # mandatory image/png is missing, or avatar is disabled
146 # (https://xmpp.org/extensions/xep-0084.html#pub-disable) 146 # (https://xmpp.org/extensions/xep-0084.html#pub-disable)
147 return None 147 return None
148 148
149 cache_data = self.host.common_cache.getMetadata(avatar_id) 149 cache_data = self.host.common_cache.get_metadata(avatar_id)
150 if not cache_data: 150 if not cache_data:
151 try: 151 try:
152 data_items, __ = await self._p.getItems( 152 data_items, __ = await self._p.get_items(
153 client, 153 client,
154 service, 154 service,
155 NS_AVATAR_DATA, 155 NS_AVATAR_DATA,
156 item_ids=[avatar_id] 156 item_ids=[avatar_id]
157 ) 157 )
170 log.warning( 170 log.warning(
171 f"invalid data element for {service.full()} with avatar ID " 171 f"invalid data element for {service.full()} with avatar ID "
172 f"{avatar_id!r}: {e}\n{data_item_elt.toXml()}" 172 f"{avatar_id!r}: {e}\n{data_item_elt.toXml()}"
173 ) 173 )
174 return None 174 return None
175 with self.host.common_cache.cacheData( 175 with self.host.common_cache.cache_data(
176 IMPORT_NAME, 176 IMPORT_NAME,
177 avatar_id, 177 avatar_id,
178 metadata["media_type"] 178 metadata["media_type"]
179 ) as f: 179 ) as f:
180 f.write(avatar_buf) 180 f.write(avatar_buf)
181 cache_data = { 181 cache_data = {
182 "path": Path(f.name), 182 "path": Path(f.name),
183 "mime_type": metadata["media_type"] 183 "mime_type": metadata["media_type"]
184 } 184 }
185 185
186 return self._i.avatarBuildMetadata( 186 return self._i.avatar_build_metadata(
187 cache_data['path'], cache_data['mime_type'], avatar_id 187 cache_data['path'], cache_data['mime_type'], avatar_id
188 ) 188 )
189 189
190 def buildItemDataElt(self, avatar_data: Dict[str, Any]) -> domish.Element: 190 def build_item_data_elt(self, avatar_data: Dict[str, Any]) -> domish.Element:
191 """Generate the item for the data node 191 """Generate the item for the data node
192 192
193 @param avatar_data: data as build by identity plugin (need to be filled with 193 @param avatar_data: data as build by identity plugin (need to be filled with
194 "cache_uid" and "base64" keys) 194 "cache_uid" and "base64" keys)
195 """ 195 """
196 data_elt = domish.Element((NS_AVATAR_DATA, "data")) 196 data_elt = domish.Element((NS_AVATAR_DATA, "data"))
197 data_elt.addContent(avatar_data["base64"]) 197 data_elt.addContent(avatar_data["base64"])
198 return pubsub.Item(id=avatar_data["cache_uid"], payload=data_elt) 198 return pubsub.Item(id=avatar_data["cache_uid"], payload=data_elt)
199 199
200 def buildItemMetadataElt(self, avatar_data: Dict[str, Any]) -> domish.Element: 200 def build_item_metadata_elt(self, avatar_data: Dict[str, Any]) -> domish.Element:
201 """Generate the item for the metadata node 201 """Generate the item for the metadata node
202 202
203 @param avatar_data: data as build by identity plugin (need to be filled with 203 @param avatar_data: data as build by identity plugin (need to be filled with
204 "cache_uid", "path", and "media_type" keys) 204 "cache_uid", "path", and "media_type" keys)
205 """ 205 """
210 info_elt["id"] = avatar_data["cache_uid"] 210 info_elt["id"] = avatar_data["cache_uid"]
211 info_elt["type"] = avatar_data["media_type"] 211 info_elt["type"] = avatar_data["media_type"]
212 info_elt["bytes"] = str(avatar_data["path"].stat().st_size) 212 info_elt["bytes"] = str(avatar_data["path"].stat().st_size)
213 return pubsub.Item(id=self._p.ID_SINGLETON, payload=metadata_elt) 213 return pubsub.Item(id=self._p.ID_SINGLETON, payload=metadata_elt)
214 214
215 async def setAvatar( 215 async def set_avatar(
216 self, 216 self,
217 client: SatXMPPEntity, 217 client: SatXMPPEntity,
218 avatar_data: Dict[str, Any], 218 avatar_data: Dict[str, Any],
219 entity: jid.JID 219 entity: jid.JID
220 ) -> None: 220 ) -> None:
225 @param entity(jid.JID): entity whose avatar must be changed 225 @param entity(jid.JID): entity whose avatar must be changed
226 """ 226 """
227 service = entity.userhostJID() 227 service = entity.userhostJID()
228 228
229 # Data 229 # Data
230 await self._p.createIfNewNode( 230 await self._p.create_if_new_node(
231 client, 231 client,
232 service, 232 service,
233 NS_AVATAR_DATA, 233 NS_AVATAR_DATA,
234 options={ 234 options={
235 self._p.OPT_ACCESS_MODEL: self._p.ACCESS_OPEN, 235 self._p.OPT_ACCESS_MODEL: self._p.ACCESS_OPEN,
236 self._p.OPT_PERSIST_ITEMS: 1, 236 self._p.OPT_PERSIST_ITEMS: 1,
237 self._p.OPT_MAX_ITEMS: 1, 237 self._p.OPT_MAX_ITEMS: 1,
238 } 238 }
239 ) 239 )
240 item_data_elt = self.buildItemDataElt(avatar_data) 240 item_data_elt = self.build_item_data_elt(avatar_data)
241 await self._p.sendItems(client, service, NS_AVATAR_DATA, [item_data_elt]) 241 await self._p.send_items(client, service, NS_AVATAR_DATA, [item_data_elt])
242 242
243 # Metadata 243 # Metadata
244 await self._p.createIfNewNode( 244 await self._p.create_if_new_node(
245 client, 245 client,
246 service, 246 service,
247 NS_AVATAR_METADATA, 247 NS_AVATAR_METADATA,
248 options={ 248 options={
249 self._p.OPT_ACCESS_MODEL: self._p.ACCESS_OPEN, 249 self._p.OPT_ACCESS_MODEL: self._p.ACCESS_OPEN,
250 self._p.OPT_PERSIST_ITEMS: 1, 250 self._p.OPT_PERSIST_ITEMS: 1,
251 self._p.OPT_MAX_ITEMS: 1, 251 self._p.OPT_MAX_ITEMS: 1,
252 } 252 }
253 ) 253 )
254 item_metadata_elt = self.buildItemMetadataElt(avatar_data) 254 item_metadata_elt = self.build_item_metadata_elt(avatar_data)
255 await self._p.sendItems(client, service, NS_AVATAR_METADATA, [item_metadata_elt]) 255 await self._p.send_items(client, service, NS_AVATAR_METADATA, [item_metadata_elt])
256 256
257 257
258 @implementer(iwokkel.IDisco) 258 @implementer(iwokkel.IDisco)
259 class XEP_0084_Handler(XMPPHandler): 259 class XEP_0084_Handler(XMPPHandler):
260 260