comparison sat_frontends/primitivus/contact_list.py @ 2624:56f94936df1e

code style reformatting using black
author Goffi <goffi@goffi.org>
date Wed, 27 Jun 2018 20:14:46 +0200
parents 81b70eeb710f
children 003b8b4b56a7
comparison
equal deleted inserted replaced
2623:49533de4540b 2624:56f94936df1e
25 from sat_frontends.primitivus.constants import Const as C 25 from sat_frontends.primitivus.constants import Const as C
26 from sat_frontends.primitivus.keys import action_key_map as a_key 26 from sat_frontends.primitivus.keys import action_key_map as a_key
27 from sat_frontends.primitivus.widget import PrimitivusWidget 27 from sat_frontends.primitivus.widget import PrimitivusWidget
28 from sat_frontends.tools import jid 28 from sat_frontends.tools import jid
29 from sat.core import log as logging 29 from sat.core import log as logging
30
30 log = logging.getLogger(__name__) 31 log = logging.getLogger(__name__)
31 from sat_frontends.quick_frontend import quick_widgets 32 from sat_frontends.quick_frontend import quick_widgets
32 33
33 34
34 class ContactList(PrimitivusWidget, QuickContactList): 35 class ContactList(PrimitivusWidget, QuickContactList):
35 PROFILES_MULTIPLE=False 36 PROFILES_MULTIPLE = False
36 PROFILES_ALLOW_NONE=False 37 PROFILES_ALLOW_NONE = False
37 signals = ['click','change'] 38 signals = ["click", "change"]
38 # FIXME: Only single profile is managed so far 39 # FIXME: Only single profile is managed so far
39 40
40 def __init__(self, host, target, on_click=None, on_change=None, user_data=None, profiles=None): 41 def __init__(
42 self, host, target, on_click=None, on_change=None, user_data=None, profiles=None
43 ):
41 QuickContactList.__init__(self, host, profiles) 44 QuickContactList.__init__(self, host, profiles)
42 self.contact_list = self.host.contact_lists[self.profile] 45 self.contact_list = self.host.contact_lists[self.profile]
43 46
44 #we now build the widget 47 # we now build the widget
45 self.status_bar = StatusBar(host) 48 self.status_bar = StatusBar(host)
46 self.frame = sat_widgets.FocusFrame(self._buildList(), None, self.status_bar) 49 self.frame = sat_widgets.FocusFrame(self._buildList(), None, self.status_bar)
47 PrimitivusWidget.__init__(self, self.frame, _(u'Contacts')) 50 PrimitivusWidget.__init__(self, self.frame, _(u"Contacts"))
48 if on_click: 51 if on_click:
49 urwid.connect_signal(self, 'click', on_click, user_data) 52 urwid.connect_signal(self, "click", on_click, user_data)
50 if on_change: 53 if on_change:
51 urwid.connect_signal(self, 'change', on_change, user_data) 54 urwid.connect_signal(self, "change", on_change, user_data)
52 self.host.addListener('notification', self.onNotification, [self.profile]) 55 self.host.addListener("notification", self.onNotification, [self.profile])
53 self.host.addListener('notificationsClear', self.onNotification, [self.profile]) 56 self.host.addListener("notificationsClear", self.onNotification, [self.profile])
54 self.postInit() 57 self.postInit()
55 58
56 def update(self, entities=None, type_=None, profile=None): 59 def update(self, entities=None, type_=None, profile=None):
57 """Update display, keep focus""" 60 """Update display, keep focus"""
58 # 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 try: 65 try:
63 self.frame.body.focus_position = position 66 self.frame.body.focus_position = position
64 except IndexError: 67 except IndexError:
65 pass 68 pass
66 self._invalidate() 69 self._invalidate()
67 self.host.redraw() # FIXME: check if can be avoided 70 self.host.redraw() # FIXME: check if can be avoided
68 71
69 def keypress(self, size, key): 72 def keypress(self, size, key):
70 # FIXME: we have a temporary behaviour here: FOCUS_SWITCH change focus globally in the parent, 73 # FIXME: we have a temporary behaviour here: FOCUS_SWITCH change focus globally in the parent,
71 # and FOCUS_UP/DOWN is transwmitter to parent if we are respectively on the first or last element 74 # and FOCUS_UP/DOWN is transwmitter to parent if we are respectively on the first or last element
72 if key in sat_widgets.FOCUS_KEYS: 75 if key in sat_widgets.FOCUS_KEYS:
73 if (key == a_key['FOCUS_SWITCH'] or (key == a_key['FOCUS_UP'] and self.frame.focus_position == 'body') or 76 if (
74 (key == a_key['FOCUS_DOWN'] and self.frame.focus_position == 'footer')): 77 key == a_key["FOCUS_SWITCH"]
78 or (key == a_key["FOCUS_UP"] and self.frame.focus_position == "body")
79 or (key == a_key["FOCUS_DOWN"] and self.frame.focus_position == "footer")
80 ):
75 return key 81 return key
76 if key == a_key['STATUS_HIDE']: #user wants to (un)hide contacts' statuses 82 if key == a_key["STATUS_HIDE"]: # user wants to (un)hide contacts' statuses
77 self.contact_list.show_status = not self.contact_list.show_status 83 self.contact_list.show_status = not self.contact_list.show_status
78 self.update() 84 self.update()
79 elif key == a_key['DISCONNECTED_HIDE']: #user wants to (un)hide disconnected contacts 85 elif (
80 self.host.bridge.setParam(C.SHOW_OFFLINE_CONTACTS, C.boolConst(not self.contact_list.show_disconnected), "General", profile_key=self.profile) 86 key == a_key["DISCONNECTED_HIDE"]
81 elif key == a_key['RESOURCES_HIDE']: #user wants to (un)hide contacts resources 87 ): # user wants to (un)hide disconnected contacts
88 self.host.bridge.setParam(
89 C.SHOW_OFFLINE_CONTACTS,
90 C.boolConst(not self.contact_list.show_disconnected),
91 "General",
92 profile_key=self.profile,
93 )
94 elif key == a_key["RESOURCES_HIDE"]: # user wants to (un)hide contacts resources
82 self.contact_list.showResources(not self.contact_list.show_resources) 95 self.contact_list.showResources(not self.contact_list.show_resources)
83 self.update() 96 self.update()
84 return super(ContactList, self).keypress(size, key) 97 return super(ContactList, self).keypress(size, key)
85 98
86 # QuickWidget methods 99 # QuickWidget methods
126 # events 139 # events
127 140
128 def _groupClicked(self, group_wid): 141 def _groupClicked(self, group_wid):
129 group = group_wid.getValue() 142 group = group_wid.getValue()
130 data = self.contact_list.getGroupData(group) 143 data = self.contact_list.getGroupData(group)
131 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)
132 self.setFocus(group) 145 self.setFocus(group)
133 self.update() 146 self.update()
134 147
135 def _contactClicked(self, use_bare_jid, contact_wid, selected): 148 def _contactClicked(self, use_bare_jid, contact_wid, selected):
136 """Method called when a contact is clicked 149 """Method called when a contact is clicked
139 @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
140 @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
141 """ 154 """
142 entity = contact_wid.data 155 entity = contact_wid.data
143 self.host.modeHint(C.MODE_INSERTION) 156 self.host.modeHint(C.MODE_INSERTION)
144 self._emit('click', entity) 157 self._emit("click", entity)
145 158
146 def onNotification(self, entity, notif, profile): 159 def onNotification(self, entity, notif, profile):
147 notifs = list(self.host.getNotifs(C.ENTITY_ALL, profile=self.profile)) 160 notifs = list(self.host.getNotifs(C.ENTITY_ALL, profile=self.profile))
148 if notifs: 161 if notifs:
149 self.title_dynamic = u"({})".format(len(notifs)) 162 self.title_dynamic = u"({})".format(len(notifs))
151 self.title_dynamic = None 164 self.title_dynamic = None
152 self.host.redraw() # FIXME: should not be necessary 165 self.host.redraw() # FIXME: should not be necessary
153 166
154 # Methods to build the widget 167 # Methods to build the widget
155 168
156 def _buildEntityWidget(self, entity, keys=None, use_bare_jid=False, with_notifs=True, with_show_attr=True, markup_prepend=None, markup_append=None, special=False): 169 def _buildEntityWidget(
170 self,
171 entity,
172 keys=None,
173 use_bare_jid=False,
174 with_notifs=True,
175 with_show_attr=True,
176 markup_prepend=None,
177 markup_append=None,
178 special=False,
179 ):
157 """Build one contact markup data 180 """Build one contact markup data
158 181
159 @param entity (jid.JID): entity to build 182 @param entity (jid.JID): entity to build
160 @param keys (iterable): value to markup, in preferred order. 183 @param keys (iterable): value to markup, in preferred order.
161 The first available key will be used. 184 The first available key will be used.
178 if keys is None: 201 if keys is None:
179 entity_txt = entity 202 entity_txt = entity
180 else: 203 else:
181 cache = self.contact_list.getCache(entity) 204 cache = self.contact_list.getCache(entity)
182 for key in keys: 205 for key in keys:
183 if key.startswith('cache_'): 206 if key.startswith("cache_"):
184 entity_txt = cache.get(key[6:]) 207 entity_txt = cache.get(key[6:])
185 else: 208 else:
186 entity_txt = getattr(entity, key) 209 entity_txt = getattr(entity, key)
187 if entity_txt: 210 if entity_txt:
188 break 211 break
191 214
192 if with_show_attr: 215 if with_show_attr:
193 show = self.contact_list.getCache(entity, C.PRESENCE_SHOW) 216 show = self.contact_list.getCache(entity, C.PRESENCE_SHOW)
194 if show is None: 217 if show is None:
195 show = C.PRESENCE_UNAVAILABLE 218 show = C.PRESENCE_UNAVAILABLE
196 show_icon, entity_attr = C.PRESENCE.get(show, ('', 'default')) 219 show_icon, entity_attr = C.PRESENCE.get(show, ("", "default"))
197 markup.insert(0, u"{} ".format(show_icon)) 220 markup.insert(0, u"{} ".format(show_icon))
198 else: 221 else:
199 entity_attr = 'default' 222 entity_attr = "default"
200 223
201 notifs = list(self.host.getNotifs(entity, exact_jid=special, profile=self.profile)) 224 notifs = list(
225 self.host.getNotifs(entity, exact_jid=special, profile=self.profile)
226 )
202 if notifs: 227 if notifs:
203 header = [('cl_notifs', u'({})'.format(len(notifs))), u' '] 228 header = [("cl_notifs", u"({})".format(len(notifs))), u" "]
204 if list(self.host.getNotifs(entity.bare, C.NOTIFY_MENTION, profile=self.profile)): 229 if list(
205 header = ('cl_mention', header) 230 self.host.getNotifs(entity.bare, C.NOTIFY_MENTION, profile=self.profile)
206 else: 231 ):
207 header = u'' 232 header = ("cl_mention", header)
233 else:
234 header = u""
208 235
209 markup.append((entity_attr, entity_txt)) 236 markup.append((entity_attr, entity_txt))
210 if markup_prepend: 237 if markup_prepend:
211 markup.insert(0, markup_prepend) 238 markup.insert(0, markup_prepend)
212 if markup_append: 239 if markup_append:
213 markup.extend(markup_append) 240 markup.extend(markup_append)
214 241
215 widget = sat_widgets.SelectableText(markup, 242 widget = sat_widgets.SelectableText(
216 selected = entity in selected, 243 markup, selected=entity in selected, header=header
217 header = header) 244 )
218 widget.data = entity 245 widget.data = entity
219 widget.comp = entity_txt.lower() # value to use for sorting 246 widget.comp = entity_txt.lower() # value to use for sorting
220 urwid.connect_signal(widget, 'change', self._contactClicked, user_args=[use_bare_jid]) 247 urwid.connect_signal(
248 widget, "change", self._contactClicked, user_args=[use_bare_jid]
249 )
221 return widget 250 return widget
222 251
223 def _buildEntities(self, content, entities): 252 def _buildEntities(self, content, entities):
224 """Add entity representation in widget list 253 """Add entity representation in widget list
225 254
229 if not entities: 258 if not entities:
230 return 259 return
231 widgets = [] # list of built widgets 260 widgets = [] # list of built widgets
232 261
233 for entity in entities: 262 for entity in entities:
234 if entity in self.contact_list._specials or not self.contact_list.entityVisible(entity): 263 if (
264 entity in self.contact_list._specials
265 or not self.contact_list.entityVisible(entity)
266 ):
235 continue 267 continue
236 markup_extra = [] 268 markup_extra = []
237 if self.contact_list.show_resources: 269 if self.contact_list.show_resources:
238 for resource in self.contact_list.getCache(entity, C.CONTACT_RESOURCES): 270 for resource in self.contact_list.getCache(entity, C.CONTACT_RESOURCES):
239 resource_disp = ('resource_main' if resource == self.contact_list.getCache(entity, C.CONTACT_MAIN_RESOURCE) else 'resource', "\n " + resource) 271 resource_disp = (
272 "resource_main"
273 if resource
274 == self.contact_list.getCache(entity, C.CONTACT_MAIN_RESOURCE)
275 else "resource",
276 "\n " + resource,
277 )
240 markup_extra.append(resource_disp) 278 markup_extra.append(resource_disp)
241 if self.contact_list.show_status: 279 if self.contact_list.show_status:
242 status = self.contact_list.getCache(jid.JID('%s/%s' % (entity, resource)), 'status') 280 status = self.contact_list.getCache(
243 status_disp = ('status', "\n " + status) if status else "" 281 jid.JID("%s/%s" % (entity, resource)), "status"
282 )
283 status_disp = ("status", "\n " + status) if status else ""
244 markup_extra.append(status_disp) 284 markup_extra.append(status_disp)
245
246 285
247 else: 286 else:
248 if self.contact_list.show_status: 287 if self.contact_list.show_status:
249 status = self.contact_list.getCache(entity, 'status') 288 status = self.contact_list.getCache(entity, "status")
250 status_disp = ('status', "\n " + status) if status else "" 289 status_disp = ("status", "\n " + status) if status else ""
251 markup_extra.append(status_disp) 290 markup_extra.append(status_disp)
252 widget = self._buildEntityWidget(entity, ('cache_nick', 'cache_name', 'node'), use_bare_jid=True, markup_append=markup_extra) 291 widget = self._buildEntityWidget(
292 entity,
293 ("cache_nick", "cache_name", "node"),
294 use_bare_jid=True,
295 markup_append=markup_extra,
296 )
253 widgets.append(widget) 297 widgets.append(widget)
254 298
255 widgets.sort(key=lambda widget: widget.comp) 299 widgets.sort(key=lambda widget: widget.comp)
256 300
257 for widget in widgets: 301 for widget in widgets:
262 specials = sorted(self.contact_list.getSpecials()) 306 specials = sorted(self.contact_list.getSpecials())
263 current = None 307 current = None
264 for entity in specials: 308 for entity in specials:
265 if current is not None and current.bare == entity.bare: 309 if current is not None and current.bare == entity.bare:
266 # nested entity (e.g. MUC private conversations) 310 # nested entity (e.g. MUC private conversations)
267 widget = self._buildEntityWidget(entity, ('resource',), markup_prepend=' ', special=True) 311 widget = self._buildEntityWidget(
312 entity, ("resource",), markup_prepend=" ", special=True
313 )
268 else: 314 else:
269 # the special widgets 315 # the special widgets
270 if entity.resource: 316 if entity.resource:
271 widget = self._buildEntityWidget(entity, ('resource',), special=True) 317 widget = self._buildEntityWidget(entity, ("resource",), special=True)
272 else: 318 else:
273 widget = self._buildEntityWidget(entity, ('cache_nick', 'cache_name', 'node'), with_show_attr=False, special=True) 319 widget = self._buildEntityWidget(
320 entity,
321 ("cache_nick", "cache_name", "node"),
322 with_show_attr=False,
323 special=True,
324 )
274 content.append(widget) 325 content.append(widget)
275 326
276 def _buildList(self): 327 def _buildList(self):
277 """Build the main contact list widget""" 328 """Build the main contact list widget"""
278 content = urwid.SimpleListWalker([]) 329 content = urwid.SimpleListWalker([])
279 330
280 self._buildSpecials(content) 331 self._buildSpecials(content)
281 if self.contact_list._specials: 332 if self.contact_list._specials:
282 content.append(urwid.Divider('=')) 333 content.append(urwid.Divider("="))
283 334
284 groups = list(self.contact_list._groups) 335 groups = list(self.contact_list._groups)
285 groups.sort(key=lambda x: x.lower() if x else x) 336 groups.sort(key=lambda x: x.lower() if x else x)
286 for group in groups: 337 for group in groups:
287 data = self.contact_list.getGroupData(group) 338 data = self.contact_list.getGroupData(group)
288 folded = data.get(C.GROUP_DATA_FOLDED, False) 339 folded = data.get(C.GROUP_DATA_FOLDED, False)
289 jids = list(data['jids']) 340 jids = list(data["jids"])
290 if group is not None and (self.contact_list.anyEntityVisible(jids) or self.contact_list.show_empty_groups): 341 if group is not None and (
291 header = '[-]' if not folded else '[+]' 342 self.contact_list.anyEntityVisible(jids)
292 widget = sat_widgets.ClickableText(group, header=header + ' ') 343 or self.contact_list.show_empty_groups
344 ):
345 header = "[-]" if not folded else "[+]"
346 widget = sat_widgets.ClickableText(group, header=header + " ")
293 content.append(widget) 347 content.append(widget)
294 urwid.connect_signal(widget, 'click', self._groupClicked) 348 urwid.connect_signal(widget, "click", self._groupClicked)
295 if not folded: 349 if not folded:
296 self._buildEntities(content, jids) 350 self._buildEntities(content, jids)
297 not_in_roster = set(self.contact_list._cache).difference(self.contact_list._roster).difference(self.contact_list._specials).difference((self.contact_list.whoami.bare,)) 351 not_in_roster = (
352 set(self.contact_list._cache)
353 .difference(self.contact_list._roster)
354 .difference(self.contact_list._specials)
355 .difference((self.contact_list.whoami.bare,))
356 )
298 if not_in_roster: 357 if not_in_roster:
299 content.append(urwid.Divider('-')) 358 content.append(urwid.Divider("-"))
300 self._buildEntities(content, not_in_roster) 359 self._buildEntities(content, not_in_roster)
301 360
302 return urwid.ListBox(content) 361 return urwid.ListBox(content)
303 362
363
304 quick_widgets.register(QuickContactList, ContactList) 364 quick_widgets.register(QuickContactList, ContactList)