comparison sat/plugins/plugin_xep_0292.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 4f02e339d184
children
comparison
equal deleted inserted replaced
4036:c4464d7ae97b 4037:524856bd7b19
69 # and other clients don't seem to use it. After discussing it on xsf@ MUC, it 69 # and other clients don't seem to use it. After discussing it on xsf@ MUC, it
70 # seems that implemeting the dedicated <IQ/> protocol is a waste of time, and thus 70 # seems that implemeting the dedicated <IQ/> protocol is a waste of time, and thus
71 # it is not done here. It is expected that this dedicated protocol will be removed 71 # it is not done here. It is expected that this dedicated protocol will be removed
72 # from a future version of the XEP. 72 # from a future version of the XEP.
73 log.info(_("vCard4 Over XMPP initialization")) 73 log.info(_("vCard4 Over XMPP initialization"))
74 host.registerNamespace("vcard4", NS_VCARD4) 74 host.register_namespace("vcard4", NS_VCARD4)
75 self.host = host 75 self.host = host
76 self._p = host.plugins["XEP-0060"] 76 self._p = host.plugins["XEP-0060"]
77 self._i = host.plugins['IDENTITY'] 77 self._i = host.plugins['IDENTITY']
78 self._i.register( 78 self._i.register(
79 IMPORT_NAME, 79 IMPORT_NAME,
80 'nicknames', 80 'nicknames',
81 partial(self.getValue, field="nicknames"), 81 partial(self.getValue, field="nicknames"),
82 partial(self.setValue, field="nicknames"), 82 partial(self.set_value, field="nicknames"),
83 priority=1000 83 priority=1000
84 ) 84 )
85 self._i.register( 85 self._i.register(
86 IMPORT_NAME, 86 IMPORT_NAME,
87 'description', 87 'description',
88 partial(self.getValue, field="description"), 88 partial(self.getValue, field="description"),
89 partial(self.setValue, field="description"), 89 partial(self.set_value, field="description"),
90 priority=1000 90 priority=1000
91 ) 91 )
92 92
93 def getHandler(self, client): 93 def get_handler(self, client):
94 return XEP_0292_Handler() 94 return XEP_0292_Handler()
95 95
96 def vcard2Dict(self, vcard_elt: domish.Element) -> Dict[str, Any]: 96 def vcard_2_dict(self, vcard_elt: domish.Element) -> Dict[str, Any]:
97 """Convert vcard element to equivalent identity metadata""" 97 """Convert vcard element to equivalent identity metadata"""
98 vcard: Dict[str, Any] = {} 98 vcard: Dict[str, Any] = {}
99 99
100 for metadata_elt in vcard_elt.elements(): 100 for metadata_elt in vcard_elt.elements():
101 # Text values 101 # Text values
102 for source_field, dest_field in text_fields.items(): 102 for source_field, dest_field in text_fields.items():
103 if metadata_elt.name == source_field: 103 if metadata_elt.name == source_field:
104 if metadata_elt.text is not None: 104 if metadata_elt.text is not None:
105 dest_type = self._i.getFieldType(dest_field) 105 dest_type = self._i.get_field_type(dest_field)
106 value = str(metadata_elt.text) 106 value = str(metadata_elt.text)
107 if dest_type is str: 107 if dest_type is str:
108 if dest_field in vcard: 108 if dest_field in vcard:
109 vcard[dest_field] += value 109 vcard[dest_field] += value
110 else: 110 else:
120 log.debug( 120 log.debug(
121 f"Following element is currently unmanaged: {metadata_elt.toXml()}" 121 f"Following element is currently unmanaged: {metadata_elt.toXml()}"
122 ) 122 )
123 return vcard 123 return vcard
124 124
125 def dict2VCard(self, vcard: dict[str, Any]) -> domish.Element: 125 def dict_2_v_card(self, vcard: dict[str, Any]) -> domish.Element:
126 """Convert vcard metadata to vCard4 element""" 126 """Convert vcard metadata to vCard4 element"""
127 vcard_elt = domish.Element((NS_VCARD4, "vcard")) 127 vcard_elt = domish.Element((NS_VCARD4, "vcard"))
128 for field, elt_name in text_fields_inv.items(): 128 for field, elt_name in text_fields_inv.items():
129 value = vcard.get(field) 129 value = vcard.get(field)
130 if value: 130 if value:
140 ) 140 )
141 141
142 return vcard_elt 142 return vcard_elt
143 143
144 @async_lru(5) 144 @async_lru(5)
145 async def getCard(self, client: SatXMPPEntity, entity: jid.JID) -> dict: 145 async def get_card(self, client: SatXMPPEntity, entity: jid.JID) -> dict:
146 try: 146 try:
147 items, metadata = await self._p.getItems( 147 items, metadata = await self._p.get_items(
148 client, entity, VCARD4_NODE, item_ids=["current"] 148 client, entity, VCARD4_NODE, item_ids=["current"]
149 ) 149 )
150 except exceptions.NotFound: 150 except exceptions.NotFound:
151 log.info(f"No vCard node found for {entity}") 151 log.info(f"No vCard node found for {entity}")
152 return {} 152 return {}
155 vcard_elt = next(item_elt.elements(NS_VCARD4, "vcard")) 155 vcard_elt = next(item_elt.elements(NS_VCARD4, "vcard"))
156 except StopIteration: 156 except StopIteration:
157 log.info(f"vCard element is not present for {entity}") 157 log.info(f"vCard element is not present for {entity}")
158 return {} 158 return {}
159 159
160 return self.vcard2Dict(vcard_elt) 160 return self.vcard_2_dict(vcard_elt)
161 161
162 async def updateVCardElt( 162 async def update_vcard_elt(
163 self, 163 self,
164 client: SatXMPPEntity, 164 client: SatXMPPEntity,
165 vcard_elt: domish.Element, 165 vcard_elt: domish.Element,
166 entity: Optional[jid.JID] = None 166 entity: Optional[jid.JID] = None
167 ) -> None: 167 ) -> None:
174 service = entity or client.jid.userhostJID() 174 service = entity or client.jid.userhostJID()
175 node_options = { 175 node_options = {
176 self._p.OPT_ACCESS_MODEL: self._p.ACCESS_OPEN, 176 self._p.OPT_ACCESS_MODEL: self._p.ACCESS_OPEN,
177 self._p.OPT_PUBLISH_MODEL: self._p.PUBLISH_MODEL_PUBLISHERS 177 self._p.OPT_PUBLISH_MODEL: self._p.PUBLISH_MODEL_PUBLISHERS
178 } 178 }
179 await self._p.createIfNewNode(client, service, VCARD4_NODE, node_options) 179 await self._p.create_if_new_node(client, service, VCARD4_NODE, node_options)
180 await self._p.sendItem( 180 await self._p.send_item(
181 client, service, VCARD4_NODE, vcard_elt, item_id=self._p.ID_SINGLETON 181 client, service, VCARD4_NODE, vcard_elt, item_id=self._p.ID_SINGLETON
182 ) 182 )
183 183
184 async def updateVCard( 184 async def update_v_card(
185 self, 185 self,
186 client: SatXMPPEntity, 186 client: SatXMPPEntity,
187 vcard: Dict[str, Any], 187 vcard: Dict[str, Any],
188 entity: Optional[jid.JID] = None, 188 entity: Optional[jid.JID] = None,
189 update: bool = True, 189 update: bool = True,
196 @param update: if True, current vCard will be retrieved and updated with given 196 @param update: if True, current vCard will be retrieved and updated with given
197 vcard (thus if False, `vcard` data will fully replace previous one). 197 vcard (thus if False, `vcard` data will fully replace previous one).
198 """ 198 """
199 service = entity or client.jid.userhostJID() 199 service = entity or client.jid.userhostJID()
200 if update: 200 if update:
201 current_vcard = await self.getCard(client, service) 201 current_vcard = await self.get_card(client, service)
202 current_vcard.update(vcard) 202 current_vcard.update(vcard)
203 vcard = current_vcard 203 vcard = current_vcard
204 vcard_elt = self.dict2VCard(vcard) 204 vcard_elt = self.dict_2_v_card(vcard)
205 await self.updateVCardElt(client, vcard_elt, service) 205 await self.update_vcard_elt(client, vcard_elt, service)
206 206
207 async def getValue( 207 async def getValue(
208 self, 208 self,
209 client: SatXMPPEntity, 209 client: SatXMPPEntity,
210 entity: jid.JID, 210 entity: jid.JID,
215 @param entity: entity from who the vCard comes 215 @param entity: entity from who the vCard comes
216 @param field: name of the field to get 216 @param field: name of the field to get
217 This has to be a string field 217 This has to be a string field
218 @return request value 218 @return request value
219 """ 219 """
220 vcard_data = await self.getCard(client, entity) 220 vcard_data = await self.get_card(client, entity)
221 return vcard_data.get(field) 221 return vcard_data.get(field)
222 222
223 async def setValue( 223 async def set_value(
224 self, 224 self,
225 client: SatXMPPEntity, 225 client: SatXMPPEntity,
226 value: Union[str, List[str]], 226 value: Union[str, List[str]],
227 entity: jid.JID, 227 entity: jid.JID,
228 field: str 228 field: str
231 231
232 @param entity: entity from who the vCard comes 232 @param entity: entity from who the vCard comes
233 @param field: name of the field to get 233 @param field: name of the field to get
234 This has to be a string field 234 This has to be a string field
235 """ 235 """
236 await self.updateVCard(client, {field: value}, entity) 236 await self.update_v_card(client, {field: value}, entity)
237 237
238 238
239 @implementer(iwokkel.IDisco) 239 @implementer(iwokkel.IDisco)
240 class XEP_0292_Handler(XMPPHandler): 240 class XEP_0292_Handler(XMPPHandler):
241 241