comparison sat_frontends/quick_frontend/quick_blog.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 be6d91572633
children 4b842c1fb686
comparison
equal deleted inserted replaced
4036:c4464d7ae97b 4037:524856bd7b19
123 while manager is not None: 123 while manager is not None:
124 level += 1 124 level += 1
125 manager = manager.manager 125 manager = manager.manager
126 return level 126 return level
127 127
128 def _addMBItems(self, items_tuple, service=None, node=None): 128 def _add_mb_items(self, items_tuple, service=None, node=None):
129 """Add Microblog items to this panel 129 """Add Microblog items to this panel
130 update is NOT called after addition 130 update is NOT called after addition
131 131
132 @param items_tuple(tuple): (items_data,items_metadata) tuple as returned by mbGet 132 @param items_tuple(tuple): (items_data,items_metadata) tuple as returned by mb_get
133 """ 133 """
134 items, metadata = items_tuple 134 items, metadata = items_tuple
135 for item in items: 135 for item in items:
136 self.addEntry(item, service=service, node=node, with_update=False) 136 self.add_entry(item, service=service, node=node, with_update=False)
137 137
138 def _addMBItemsWithComments(self, items_tuple, service=None, node=None): 138 def _add_mb_items_with_comments(self, items_tuple, service=None, node=None):
139 """Add Microblog items to this panel 139 """Add Microblog items to this panel
140 update is NOT called after addition 140 update is NOT called after addition
141 141
142 @param items_tuple(tuple): (items_data,items_metadata) tuple as returned by mbGet 142 @param items_tuple(tuple): (items_data,items_metadata) tuple as returned by mb_get
143 """ 143 """
144 items, metadata = items_tuple 144 items, metadata = items_tuple
145 for item, comments in items: 145 for item, comments in items:
146 self.addEntry(item, comments, service=service, node=node, with_update=False) 146 self.add_entry(item, comments, service=service, node=node, with_update=False)
147 147
148 def addEntry(self, item=None, comments=None, service=None, node=None, 148 def add_entry(self, item=None, comments=None, service=None, node=None,
149 with_update=True, editable=False, edit_entry=False): 149 with_update=True, editable=False, edit_entry=False):
150 """Add a microblog entry 150 """Add a microblog entry
151 151
152 @param editable (bool): True if the entry can be modified 152 @param editable (bool): True if the entry can be modified
153 @param item (dict, None): blog item data, or None for an empty entry 153 @param item (dict, None): blog item data, or None for an empty entry
158 @param edit_entry(bool): if True, will be in self.edit_entry instead of 158 @param edit_entry(bool): if True, will be in self.edit_entry instead of
159 self.entries, so it can be managed separately (e.g. first or last 159 self.entries, so it can be managed separately (e.g. first or last
160 entry regardless of sorting) 160 entry regardless of sorting)
161 """ 161 """
162 new_entry = ENTRY_CLS(self, item, comments, service=service, node=node) 162 new_entry = ENTRY_CLS(self, item, comments, service=service, node=node)
163 new_entry.setEditable(editable) 163 new_entry.set_editable(editable)
164 if edit_entry: 164 if edit_entry:
165 self.edit_entry = new_entry 165 self.edit_entry = new_entry
166 else: 166 else:
167 self.entries.append(new_entry) 167 self.entries.append(new_entry)
168 if with_update: 168 if with_update:
173 """Update the display with entries 173 """Update the display with entries
174 174
175 @param entry (Entry, None): if not None, must be the new entry. 175 @param entry (Entry, None): if not None, must be the new entry.
176 If None, all the items will be checked to update the display 176 If None, all the items will be checked to update the display
177 """ 177 """
178 # update is separated from addEntry to allow adding 178 # update is separated from add_entry to allow adding
179 # several entries at once, and updating at the end 179 # several entries at once, and updating at the end
180 raise NotImplementedError 180 raise NotImplementedError
181 181
182 182
183 class Entry(EntriesManager): 183 class Entry(EntriesManager):
230 230
231 def refresh(self): 231 def refresh(self):
232 """Refresh the display when data have been modified""" 232 """Refresh the display when data have been modified"""
233 pass 233 pass
234 234
235 def setEditable(self, editable=True): 235 def set_editable(self, editable=True):
236 """tell if the entry can be edited or not 236 """tell if the entry can be edited or not
237 237
238 @param editable(bool): True if the entry can be edited 238 @param editable(bool): True if the entry can be edited
239 """ 239 """
240 # XXX: we don't use @property as property setter doesn't play well with pyjamas 240 # XXX: we don't use @property as property setter doesn't play well with pyjamas
241 raise NotImplementedError 241 raise NotImplementedError
242 242
243 def addComments(self, comments_data): 243 def add_comments(self, comments_data):
244 """Add comments to this entry by calling addEntry repeatidly 244 """Add comments to this entry by calling add_entry repeatidly
245 245
246 @param comments_data(tuple): data as returned by mbGetFromMany*RTResults 246 @param comments_data(tuple): data as returned by mb_get_from_many*RTResults
247 """ 247 """
248 # TODO: manage seperator between comments of coming from different services/nodes 248 # TODO: manage seperator between comments of coming from different services/nodes
249 for data in comments_data: 249 for data in comments_data:
250 service, node, failure, comments, metadata = data 250 service, node, failure, comments, metadata = data
251 for comment in comments: 251 for comment in comments:
252 if not failure: 252 if not failure:
253 self.addEntry(comment, service=jid.JID(service), node=node) 253 self.add_entry(comment, service=jid.JID(service), node=node)
254 else: 254 else:
255 log.warning("getting comment failed: {}".format(failure)) 255 log.warning("getting comment failed: {}".format(failure))
256 self.update() 256 self.update()
257 257
258 def send(self): 258 def send(self):
284 mb_data["allow_comments"] = True 284 mb_data["allow_comments"] = True
285 285
286 if self.blog.new_message_target == C.GROUP: 286 if self.blog.new_message_target == C.GROUP:
287 mb_data['groups'] = list(self.blog.targets) 287 mb_data['groups'] = list(self.blog.targets)
288 288
289 self.blog.host.bridge.mbSend( 289 self.blog.host.bridge.mb_send(
290 str(self.service or ""), 290 str(self.service or ""),
291 self.node or "", 291 self.node or "",
292 data_format.serialise(mb_data), 292 data_format.serialise(mb_data),
293 profile=self.blog.profile, 293 profile=self.blog.profile,
294 ) 294 )
325 325
326 if there is a comments node, it will be purged too 326 if there is a comments node, it will be purged too
327 """ 327 """
328 # TODO: manage several comments nodes case. 328 # TODO: manage several comments nodes case.
329 if self.item.comments: 329 if self.item.comments:
330 self.blog.host.bridge.psNodeDelete( 330 self.blog.host.bridge.ps_node_delete(
331 str(self.item.comments_service) or "", 331 str(self.item.comments_service) or "",
332 self.item.comments_node, 332 self.item.comments_node,
333 profile=self.blog.profile, 333 profile=self.blog.profile,
334 ) 334 )
335 self.blog.host.bridge.mbRetract( 335 self.blog.host.bridge.mb_retract(
336 str(self.service or ""), 336 str(self.service or ""),
337 self.node or "", 337 self.node or "",
338 self.item.id, 338 self.item.id,
339 profile=self.blog.profile, 339 profile=self.blog.profile,
340 ) 340 )
360 else: 360 else:
361 assert isinstance(targets[0], str) 361 assert isinstance(targets[0], str)
362 quick_widgets.QuickWidget.__init__(self, host, targets[0], C.PROF_KEY_NONE) 362 quick_widgets.QuickWidget.__init__(self, host, targets[0], C.PROF_KEY_NONE)
363 for target in targets[1:]: 363 for target in targets[1:]:
364 assert isinstance(target, str) 364 assert isinstance(target, str)
365 self.addTarget(target) 365 self.add_target(target)
366 self._targets_type = C.GROUP 366 self._targets_type = C.GROUP
367 367
368 @property 368 @property
369 def new_message_target(self): 369 def new_message_target(self):
370 if self._targets_type == C.ALL: 370 if self._targets_type == C.ALL:
377 def __str__(self): 377 def __str__(self):
378 return "Blog Widget [target: {}, profile: {}]".format( 378 return "Blog Widget [target: {}, profile: {}]".format(
379 ", ".join(self.targets), self.profile 379 ", ".join(self.targets), self.profile
380 ) 380 )
381 381
382 def _getResultsCb(self, data, rt_session): 382 def _get_results_cb(self, data, rt_session):
383 remaining, results = data 383 remaining, results = data
384 log.debug( 384 log.debug(
385 "Got {got_len} results, {rem_len} remaining".format( 385 "Got {got_len} results, {rem_len} remaining".format(
386 got_len=len(results), rem_len=remaining 386 got_len=len(results), rem_len=remaining
387 ) 387 )
391 for item_data in items_data: 391 for item_data in items_data:
392 item_data[0] = data_format.deserialise(item_data[0]) 392 item_data[0] = data_format.deserialise(item_data[0])
393 for item_metadata in item_data[1]: 393 for item_metadata in item_data[1]:
394 item_metadata[3] = [data_format.deserialise(i) for i in item_metadata[3]] 394 item_metadata[3] = [data_format.deserialise(i) for i in item_metadata[3]]
395 if not failure: 395 if not failure:
396 self._addMBItemsWithComments((items_data, metadata), 396 self._add_mb_items_with_comments((items_data, metadata),
397 service=jid.JID(service)) 397 service=jid.JID(service))
398 398
399 self.update() 399 self.update()
400 if remaining: 400 if remaining:
401 self._getResults(rt_session) 401 self._get_results(rt_session)
402 402
403 def _getResultsEb(self, failure): 403 def _get_results_eb(self, failure):
404 log.warning("microblog getFromMany error: {}".format(failure)) 404 log.warning("microblog get_from_many error: {}".format(failure))
405 405
406 def _getResults(self, rt_session): 406 def _get_results(self, rt_session):
407 """Manage results from mbGetFromMany RT Session 407 """Manage results from mb_get_from_many RT Session
408 408
409 @param rt_session(str): session id as returned by mbGetFromMany 409 @param rt_session(str): session id as returned by mb_get_from_many
410 """ 410 """
411 self.host.bridge.mbGetFromManyWithCommentsRTResult( 411 self.host.bridge.mb_get_from_many_with_comments_rt_result(
412 rt_session, 412 rt_session,
413 profile=self.profile, 413 profile=self.profile,
414 callback=lambda data: self._getResultsCb(data, rt_session), 414 callback=lambda data: self._get_results_cb(data, rt_session),
415 errback=self._getResultsEb, 415 errback=self._get_results_eb,
416 ) 416 )
417 417
418 def getAll(self): 418 def get_all(self):
419 """Get all (micro)blogs from self.targets""" 419 """Get all (micro)blogs from self.targets"""
420 420
421 def gotSession(rt_session): 421 def got_session(rt_session):
422 self._getResults(rt_session) 422 self._get_results(rt_session)
423 423
424 if self._targets_type in (C.ALL, C.GROUP): 424 if self._targets_type in (C.ALL, C.GROUP):
425 targets = tuple(self.targets) if self._targets_type is C.GROUP else () 425 targets = tuple(self.targets) if self._targets_type is C.GROUP else ()
426 self.host.bridge.mbGetFromManyWithComments( 426 self.host.bridge.mb_get_from_many_with_comments(
427 self._targets_type, 427 self._targets_type,
428 targets, 428 targets,
429 10, 429 10,
430 10, 430 10,
431 {}, 431 {},
432 {"subscribe": C.BOOL_TRUE}, 432 {"subscribe": C.BOOL_TRUE},
433 profile=self.profile, 433 profile=self.profile,
434 callback=gotSession, 434 callback=got_session,
435 ) 435 )
436 own_pep = self.host.whoami.bare 436 own_pep = self.host.whoami.bare
437 self.host.bridge.mbGetFromManyWithComments( 437 self.host.bridge.mb_get_from_many_with_comments(
438 C.JID, 438 C.JID,
439 (str(own_pep),), 439 (str(own_pep),),
440 10, 440 10,
441 10, 441 10,
442 {}, 442 {},
443 {}, 443 {},
444 profile=self.profile, 444 profile=self.profile,
445 callback=gotSession, 445 callback=got_session,
446 ) 446 )
447 else: 447 else:
448 raise NotImplementedError( 448 raise NotImplementedError(
449 "{} target type is not managed".format(self._targets_type) 449 "{} target type is not managed".format(self._targets_type)
450 ) 450 )
451 451
452 def isJidAccepted(self, jid_): 452 def is_jid_accepted(self, jid_):
453 """Tell if a jid is actepted and must be shown in this panel 453 """Tell if a jid is actepted and must be shown in this panel
454 454
455 @param jid_(jid.JID): jid to check 455 @param jid_(jid.JID): jid to check
456 @return: True if the jid is accepted 456 @return: True if the jid is accepted
457 """ 457 """
458 if self._targets_type == C.ALL: 458 if self._targets_type == C.ALL:
459 return True 459 return True
460 assert self._targets_type is C.GROUP # we don't manage other types for now 460 assert self._targets_type is C.GROUP # we don't manage other types for now
461 for group in self.targets: 461 for group in self.targets:
462 if self.host.contact_lists[self.profile].isEntityInGroup(jid_, group): 462 if self.host.contact_lists[self.profile].is_entity_in_group(jid_, group):
463 return True 463 return True
464 return False 464 return False
465 465
466 def addEntryIfAccepted(self, service, node, mb_data, groups, profile): 466 def add_entry_if_accepted(self, service, node, mb_data, groups, profile):
467 """add entry to this panel if it's acceptable 467 """add entry to this panel if it's acceptable
468 468
469 This method check if the entry is new or an update, 469 This method check if the entry is new or an update,
470 if it below to a know node, or if it acceptable anyway 470 if it below to a know node, or if it acceptable anyway
471 @param service(jid.JID): jid of the emitting pubsub service 471 @param service(jid.JID): jid of the emitting pubsub service
483 parent_entries = self.node2entries[(service, node)] 483 parent_entries = self.node2entries[(service, node)]
484 except: 484 except:
485 # The node is unknown, 485 # The node is unknown,
486 # we need to check that we can accept the entry 486 # we need to check that we can accept the entry
487 if ( 487 if (
488 self.isJidAccepted(service) 488 self.is_jid_accepted(service)
489 or ( 489 or (
490 groups is None 490 groups is None
491 and service == self.host.profiles[self.profile].whoami.bare 491 and service == self.host.profiles[self.profile].whoami.bare
492 ) 492 )
493 or (groups and groups.intersection(self.targets)) 493 or (groups and groups.intersection(self.targets))
494 ): 494 ):
495 self.addEntry(mb_data, service=service, node=node) 495 self.add_entry(mb_data, service=service, node=node)
496 else: 496 else:
497 # the entry is a comment in a known node 497 # the entry is a comment in a known node
498 for parent_entry in parent_entries: 498 for parent_entry in parent_entries:
499 parent_entry.addEntry(mb_data, service=service, node=node) 499 parent_entry.add_entry(mb_data, service=service, node=node)
500 else: 500 else:
501 # The entry exist, it's an update 501 # The entry exist, it's an update
502 entry.reset(mb_data) 502 entry.reset(mb_data)
503 entry.refresh() 503 entry.refresh()
504 504
505 def deleteEntryIfPresent(self, service, node, item_id, profile): 505 def delete_entry_if_present(self, service, node, item_id, profile):
506 """Delete and entry if present in this QuickBlog 506 """Delete and entry if present in this QuickBlog
507 507
508 @param sender(jid.JID): jid of the entry sender 508 @param sender(jid.JID): jid of the entry sender
509 @param mb_data: microblog data 509 @param mb_data: microblog data
510 @param service(jid.JID): sending service 510 @param service(jid.JID): sending service
516 pass 516 pass
517 else: 517 else:
518 entry.delete() 518 entry.delete()
519 519
520 520
521 def registerClass(type_, cls): 521 def register_class(type_, cls):
522 global ENTRY_CLS, COMMENTS_CLS 522 global ENTRY_CLS, COMMENTS_CLS
523 if type_ == "ENTRY": 523 if type_ == "ENTRY":
524 ENTRY_CLS = cls 524 ENTRY_CLS = cls
525 elif type == "COMMENT": 525 elif type == "COMMENT":
526 COMMENTS_CLS = cls 526 COMMENTS_CLS = cls