Mercurial > libervia-backend
comparison sat_frontends/primitivus/contact_list.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 |
---|---|
44 QuickContactList.__init__(self, host, profiles) | 44 QuickContactList.__init__(self, host, profiles) |
45 self.contact_list = self.host.contact_lists[self.profile] | 45 self.contact_list = self.host.contact_lists[self.profile] |
46 | 46 |
47 # we now build the widget | 47 # we now build the widget |
48 self.status_bar = StatusBar(host) | 48 self.status_bar = StatusBar(host) |
49 self.frame = sat_widgets.FocusFrame(self._buildList(), None, self.status_bar) | 49 self.frame = sat_widgets.FocusFrame(self._build_list(), None, self.status_bar) |
50 PrimitivusWidget.__init__(self, self.frame, _("Contacts")) | 50 PrimitivusWidget.__init__(self, self.frame, _("Contacts")) |
51 if on_click: | 51 if on_click: |
52 urwid.connect_signal(self, "click", on_click, user_data) | 52 urwid.connect_signal(self, "click", on_click, user_data) |
53 if on_change: | 53 if on_change: |
54 urwid.connect_signal(self, "change", on_change, user_data) | 54 urwid.connect_signal(self, "change", on_change, user_data) |
55 self.host.addListener("notification", self.onNotification, [self.profile]) | 55 self.host.addListener("notification", self.on_notification, [self.profile]) |
56 self.host.addListener("notificationsClear", self.onNotification, [self.profile]) | 56 self.host.addListener("notificationsClear", self.on_notification, [self.profile]) |
57 self.postInit() | 57 self.post_init() |
58 | 58 |
59 def update(self, entities=None, type_=None, profile=None): | 59 def update(self, entities=None, type_=None, profile=None): |
60 """Update display, keep focus""" | 60 """Update display, keep focus""" |
61 # FIXME: full update is done each time, must handle entities, type_ and profile | 61 # FIXME: full update is done each time, must handle entities, type_ and profile |
62 widget, position = self.frame.body.get_focus() | 62 widget, position = self.frame.body.get_focus() |
63 self.frame.body = self._buildList() | 63 self.frame.body = self._build_list() |
64 if position: | 64 if position: |
65 try: | 65 try: |
66 self.frame.body.focus_position = position | 66 self.frame.body.focus_position = position |
67 except IndexError: | 67 except IndexError: |
68 pass | 68 pass |
83 self.contact_list.show_status = not self.contact_list.show_status | 83 self.contact_list.show_status = not self.contact_list.show_status |
84 self.update() | 84 self.update() |
85 elif ( | 85 elif ( |
86 key == a_key["DISCONNECTED_HIDE"] | 86 key == a_key["DISCONNECTED_HIDE"] |
87 ): # user wants to (un)hide disconnected contacts | 87 ): # user wants to (un)hide disconnected contacts |
88 self.host.bridge.setParam( | 88 self.host.bridge.param_set( |
89 C.SHOW_OFFLINE_CONTACTS, | 89 C.SHOW_OFFLINE_CONTACTS, |
90 C.boolConst(not self.contact_list.show_disconnected), | 90 C.bool_const(not self.contact_list.show_disconnected), |
91 "General", | 91 "General", |
92 profile_key=self.profile, | 92 profile_key=self.profile, |
93 ) | 93 ) |
94 elif key == a_key["RESOURCES_HIDE"]: # user wants to (un)hide contacts resources | 94 elif key == a_key["RESOURCES_HIDE"]: # user wants to (un)hide contacts resources |
95 self.contact_list.showResources(not self.contact_list.show_resources) | 95 self.contact_list.show_resources(not self.contact_list.show_resources) |
96 self.update() | 96 self.update() |
97 return super(ContactList, self).keypress(size, key) | 97 return super(ContactList, self).keypress(size, key) |
98 | 98 |
99 # QuickWidget methods | 99 # QuickWidget methods |
100 | 100 |
101 @staticmethod | 101 @staticmethod |
102 def getWidgetHash(target, profiles): | 102 def get_widget_hash(target, profiles): |
103 profiles = sorted(profiles) | 103 profiles = sorted(profiles) |
104 return tuple(profiles) | 104 return tuple(profiles) |
105 | 105 |
106 # modify the contact list | 106 # modify the contact list |
107 | 107 |
108 def setFocus(self, text, select=False): | 108 def set_focus(self, text, select=False): |
109 """give focus to the first element that matches the given text. You can also | 109 """give focus to the first element that matches the given text. You can also |
110 pass in text a sat_frontends.tools.jid.JID (it's a subclass of unicode). | 110 pass in text a sat_frontends.tools.jid.JID (it's a subclass of unicode). |
111 | 111 |
112 @param text: contact group name, contact or muc userhost, muc private dialog jid | 112 @param text: contact group name, contact or muc userhost, muc private dialog jid |
113 @param select: if True, the element is also clicked | 113 @param select: if True, the element is also clicked |
115 idx = 0 | 115 idx = 0 |
116 for widget in self.frame.body.body: | 116 for widget in self.frame.body.body: |
117 try: | 117 try: |
118 if isinstance(widget, sat_widgets.ClickableText): | 118 if isinstance(widget, sat_widgets.ClickableText): |
119 # contact group | 119 # contact group |
120 value = widget.getValue() | 120 value = widget.get_value() |
121 elif isinstance(widget, sat_widgets.SelectableText): | 121 elif isinstance(widget, sat_widgets.SelectableText): |
122 # contact or muc | 122 # contact or muc |
123 value = widget.data | 123 value = widget.data |
124 else: | 124 else: |
125 # Divider instance | 125 # Divider instance |
126 continue | 126 continue |
127 # there's sometimes a leading space | 127 # there's sometimes a leading space |
128 if text.strip() == value.strip(): | 128 if text.strip() == value.strip(): |
129 self.frame.body.focus_position = idx | 129 self.frame.body.focus_position = idx |
130 if select: | 130 if select: |
131 self._contactClicked(False, widget, True) | 131 self._contact_clicked(False, widget, True) |
132 return | 132 return |
133 except AttributeError: | 133 except AttributeError: |
134 pass | 134 pass |
135 idx += 1 | 135 idx += 1 |
136 | 136 |
137 log.debug("Not element found for {} in setFocus".format(text)) | 137 log.debug("Not element found for {} in set_focus".format(text)) |
138 | 138 |
139 # events | 139 # events |
140 | 140 |
141 def _groupClicked(self, group_wid): | 141 def _group_clicked(self, group_wid): |
142 group = group_wid.getValue() | 142 group = group_wid.get_value() |
143 data = self.contact_list.getGroupData(group) | 143 data = self.contact_list.get_group_data(group) |
144 data[C.GROUP_DATA_FOLDED] = not data.setdefault(C.GROUP_DATA_FOLDED, False) | 144 data[C.GROUP_DATA_FOLDED] = not data.setdefault(C.GROUP_DATA_FOLDED, False) |
145 self.setFocus(group) | 145 self.set_focus(group) |
146 self.update() | 146 self.update() |
147 | 147 |
148 def _contactClicked(self, use_bare_jid, contact_wid, selected): | 148 def _contact_clicked(self, use_bare_jid, contact_wid, selected): |
149 """Method called when a contact is clicked | 149 """Method called when a contact is clicked |
150 | 150 |
151 @param use_bare_jid: True if use_bare_jid is set in self._buildEntityWidget. | 151 @param use_bare_jid: True if use_bare_jid is set in self._build_entity_widget. |
152 @param contact_wid: widget of the contact, must have the entity set in data attribute | 152 @param contact_wid: widget of the contact, must have the entity set in data attribute |
153 @param selected: boolean returned by the widget, telling if it is selected | 153 @param selected: boolean returned by the widget, telling if it is selected |
154 """ | 154 """ |
155 entity = contact_wid.data | 155 entity = contact_wid.data |
156 self.host.modeHint(C.MODE_INSERTION) | 156 self.host.mode_hint(C.MODE_INSERTION) |
157 self._emit("click", entity) | 157 self._emit("click", entity) |
158 | 158 |
159 def onNotification(self, entity, notif, profile): | 159 def on_notification(self, entity, notif, profile): |
160 notifs = list(self.host.getNotifs(C.ENTITY_ALL, profile=self.profile)) | 160 notifs = list(self.host.get_notifs(C.ENTITY_ALL, profile=self.profile)) |
161 if notifs: | 161 if notifs: |
162 self.title_dynamic = "({})".format(len(notifs)) | 162 self.title_dynamic = "({})".format(len(notifs)) |
163 else: | 163 else: |
164 self.title_dynamic = None | 164 self.title_dynamic = None |
165 self.host.redraw() # FIXME: should not be necessary | 165 self.host.redraw() # FIXME: should not be necessary |
166 | 166 |
167 # Methods to build the widget | 167 # Methods to build the widget |
168 | 168 |
169 def _buildEntityWidget( | 169 def _build_entity_widget( |
170 self, | 170 self, |
171 entity, | 171 entity, |
172 keys=None, | 172 keys=None, |
173 use_bare_jid=False, | 173 use_bare_jid=False, |
174 with_notifs=True, | 174 with_notifs=True, |
220 markup.insert(0, "{} ".format(show_icon)) | 220 markup.insert(0, "{} ".format(show_icon)) |
221 else: | 221 else: |
222 entity_attr = "default" | 222 entity_attr = "default" |
223 | 223 |
224 notifs = list( | 224 notifs = list( |
225 self.host.getNotifs(entity, exact_jid=special, profile=self.profile) | 225 self.host.get_notifs(entity, exact_jid=special, profile=self.profile) |
226 ) | 226 ) |
227 mentions = list( | 227 mentions = list( |
228 self.host.getNotifs(entity.bare, C.NOTIFY_MENTION, profile=self.profile) | 228 self.host.get_notifs(entity.bare, C.NOTIFY_MENTION, profile=self.profile) |
229 ) | 229 ) |
230 if notifs or mentions: | 230 if notifs or mentions: |
231 attr = 'cl_mention' if mentions else 'cl_notifs' | 231 attr = 'cl_mention' if mentions else 'cl_notifs' |
232 header = [(attr, "({})".format(len(notifs) + len(mentions))), " "] | 232 header = [(attr, "({})".format(len(notifs) + len(mentions))), " "] |
233 else: | 233 else: |
243 markup, selected=entity in selected, header=header | 243 markup, selected=entity in selected, header=header |
244 ) | 244 ) |
245 widget.data = entity | 245 widget.data = entity |
246 widget.comp = entity_txt.lower() # value to use for sorting | 246 widget.comp = entity_txt.lower() # value to use for sorting |
247 urwid.connect_signal( | 247 urwid.connect_signal( |
248 widget, "change", self._contactClicked, user_args=[use_bare_jid] | 248 widget, "change", self._contact_clicked, user_args=[use_bare_jid] |
249 ) | 249 ) |
250 return widget | 250 return widget |
251 | 251 |
252 def _buildEntities(self, content, entities): | 252 def _build_entities(self, content, entities): |
253 """Add entity representation in widget list | 253 """Add entity representation in widget list |
254 | 254 |
255 @param content: widget list, e.g. SimpleListWalker | 255 @param content: widget list, e.g. SimpleListWalker |
256 @param entities (iterable): iterable of JID to display | 256 @param entities (iterable): iterable of JID to display |
257 """ | 257 """ |
260 widgets = [] # list of built widgets | 260 widgets = [] # list of built widgets |
261 | 261 |
262 for entity in entities: | 262 for entity in entities: |
263 if ( | 263 if ( |
264 entity in self.contact_list._specials | 264 entity in self.contact_list._specials |
265 or not self.contact_list.entityVisible(entity) | 265 or not self.contact_list.entity_visible(entity) |
266 ): | 266 ): |
267 continue | 267 continue |
268 markup_extra = [] | 268 markup_extra = [] |
269 if self.contact_list.show_resources: | 269 if self.contact_list.show_resources: |
270 for resource in self.contact_list.getCache(entity, C.CONTACT_RESOURCES): | 270 for resource in self.contact_list.getCache(entity, C.CONTACT_RESOURCES): |
286 else: | 286 else: |
287 if self.contact_list.show_status: | 287 if self.contact_list.show_status: |
288 status = self.contact_list.getCache(entity, "status", default=None) | 288 status = self.contact_list.getCache(entity, "status", default=None) |
289 status_disp = ("status", "\n " + status) if status else "" | 289 status_disp = ("status", "\n " + status) if status else "" |
290 markup_extra.append(status_disp) | 290 markup_extra.append(status_disp) |
291 widget = self._buildEntityWidget( | 291 widget = self._build_entity_widget( |
292 entity, | 292 entity, |
293 ("cache_nick", "cache_name", "node"), | 293 ("cache_nick", "cache_name", "node"), |
294 use_bare_jid=True, | 294 use_bare_jid=True, |
295 markup_append=markup_extra, | 295 markup_append=markup_extra, |
296 ) | 296 ) |
299 widgets.sort(key=lambda widget: widget.comp) | 299 widgets.sort(key=lambda widget: widget.comp) |
300 | 300 |
301 for widget in widgets: | 301 for widget in widgets: |
302 content.append(widget) | 302 content.append(widget) |
303 | 303 |
304 def _buildSpecials(self, content): | 304 def _build_specials(self, content): |
305 """Build the special entities""" | 305 """Build the special entities""" |
306 specials = sorted(self.contact_list.getSpecials()) | 306 specials = sorted(self.contact_list.get_specials()) |
307 current = None | 307 current = None |
308 for entity in specials: | 308 for entity in specials: |
309 if current is not None and current.bare == entity.bare: | 309 if current is not None and current.bare == entity.bare: |
310 # nested entity (e.g. MUC private conversations) | 310 # nested entity (e.g. MUC private conversations) |
311 widget = self._buildEntityWidget( | 311 widget = self._build_entity_widget( |
312 entity, ("resource",), markup_prepend=" ", special=True | 312 entity, ("resource",), markup_prepend=" ", special=True |
313 ) | 313 ) |
314 else: | 314 else: |
315 # the special widgets | 315 # the special widgets |
316 if entity.resource: | 316 if entity.resource: |
317 widget = self._buildEntityWidget(entity, ("resource",), special=True) | 317 widget = self._build_entity_widget(entity, ("resource",), special=True) |
318 else: | 318 else: |
319 widget = self._buildEntityWidget( | 319 widget = self._build_entity_widget( |
320 entity, | 320 entity, |
321 ("cache_nick", "cache_name", "node"), | 321 ("cache_nick", "cache_name", "node"), |
322 with_show_attr=False, | 322 with_show_attr=False, |
323 special=True, | 323 special=True, |
324 ) | 324 ) |
325 content.append(widget) | 325 content.append(widget) |
326 | 326 |
327 def _buildList(self): | 327 def _build_list(self): |
328 """Build the main contact list widget""" | 328 """Build the main contact list widget""" |
329 content = urwid.SimpleListWalker([]) | 329 content = urwid.SimpleListWalker([]) |
330 | 330 |
331 self._buildSpecials(content) | 331 self._build_specials(content) |
332 if self.contact_list._specials: | 332 if self.contact_list._specials: |
333 content.append(urwid.Divider("=")) | 333 content.append(urwid.Divider("=")) |
334 | 334 |
335 groups = list(self.contact_list._groups) | 335 groups = list(self.contact_list._groups) |
336 groups.sort(key=lambda x: x.lower() if x else '') | 336 groups.sort(key=lambda x: x.lower() if x else '') |
337 for group in groups: | 337 for group in groups: |
338 data = self.contact_list.getGroupData(group) | 338 data = self.contact_list.get_group_data(group) |
339 folded = data.get(C.GROUP_DATA_FOLDED, False) | 339 folded = data.get(C.GROUP_DATA_FOLDED, False) |
340 jids = list(data["jids"]) | 340 jids = list(data["jids"]) |
341 if group is not None and ( | 341 if group is not None and ( |
342 self.contact_list.anyEntityVisible(jids) | 342 self.contact_list.any_entity_visible(jids) |
343 or self.contact_list.show_empty_groups | 343 or self.contact_list.show_empty_groups |
344 ): | 344 ): |
345 header = "[-]" if not folded else "[+]" | 345 header = "[-]" if not folded else "[+]" |
346 widget = sat_widgets.ClickableText(group, header=header + " ") | 346 widget = sat_widgets.ClickableText(group, header=header + " ") |
347 content.append(widget) | 347 content.append(widget) |
348 urwid.connect_signal(widget, "click", self._groupClicked) | 348 urwid.connect_signal(widget, "click", self._group_clicked) |
349 if not folded: | 349 if not folded: |
350 self._buildEntities(content, jids) | 350 self._build_entities(content, jids) |
351 not_in_roster = ( | 351 not_in_roster = ( |
352 set(self.contact_list._cache) | 352 set(self.contact_list._cache) |
353 .difference(self.contact_list._roster) | 353 .difference(self.contact_list._roster) |
354 .difference(self.contact_list._specials) | 354 .difference(self.contact_list._specials) |
355 .difference((self.contact_list.whoami.bare,)) | 355 .difference((self.contact_list.whoami.bare,)) |
356 ) | 356 ) |
357 if not_in_roster: | 357 if not_in_roster: |
358 content.append(urwid.Divider("-")) | 358 content.append(urwid.Divider("-")) |
359 self._buildEntities(content, not_in_roster) | 359 self._build_entities(content, not_in_roster) |
360 | 360 |
361 return urwid.ListBox(content) | 361 return urwid.ListBox(content) |
362 | 362 |
363 | 363 |
364 quick_widgets.register(QuickContactList, ContactList) | 364 quick_widgets.register(QuickContactList, ContactList) |