From 71f813af289ff4df6e4721f56c907d78aa609e69 Mon Sep 17 00:00:00 2001 From: mathieui Date: Wed, 1 Aug 2012 01:06:57 +0200 Subject: Add a roster_group_sort option, which works like roster_sort - defaults to "name" (sort by group name) - document it - also, micro-optimize get_nb_connected_contacts() --- data/default_config.cfg | 15 +++++++++++++-- doc/en/configure.txt | 13 +++++++++++++ src/roster.py | 42 +++++++++++++++++++++++++++++++++++++----- src/windows.py | 3 ++- 4 files changed, 65 insertions(+), 8 deletions(-) diff --git a/data/default_config.cfg b/data/default_config.cfg index aedd2413..f75ae14b 100644 --- a/data/default_config.cfg +++ b/data/default_config.cfg @@ -229,13 +229,24 @@ roster_show_offline = false # - reverse: reverse the sorting # - jid: sort by JID (alphabetical order) # - show: sort by show (available/away/xa/…) -# - name: Sort by roster name (if no name, then the bare jid is used) -# - resource: Sort by resource number +# - name: sort by roster name (if no name, then the bare jid is used) +# - resource: sort by resource number # You can arrange them however you like, and you have to separate them with # underscores "_". Keep in mind that if there are more than 3 or 4 your sorting # is most likely inefficient. roster_sort = jid_show +# How to sort the roster groups. +# The principles are the same as roster_sort. +# Available methods are: +# - reverse: reverse the sorting +# - name: sort by group name (alphabetical order) +# - fold: sort unfolded/folded +# - connected: sort by number of connected contacts +# - size: sort by group size +# - none: put the "none" group (if any) at the end of the list +roster_group_sort = name + # The terminal can beep on various event. Put the event you want in a list # (separated by spaces). # The events can be diff --git a/doc/en/configure.txt b/doc/en/configure.txt index aa880d7b..fc854dba 100644 --- a/doc/en/configure.txt +++ b/doc/en/configure.txt @@ -296,6 +296,19 @@ section of this documentation. separated by underscores ("_"). If there are more than 3 or 4 chained sorting methods, your sorting is most likely inefficient. +*roster_group_sort*:: name + + How to sort the roster groups. The principles are the same as _roster_sort_ + (see above). + + Available methods are: + * reverse: reverse the current sorting + * name: sort by group name (alphabetical order) + * fold: sort by unfolded/folded + * connected: sort by number of connected contacts + * size: sort by group size + * none: put the "none" group (if any) at the end of the list + *beep_on*:: highlight private The terminal can beep on various event. Put the event you want in a list diff --git a/src/roster.py b/src/roster.py index 84771678..8d59e345 100644 --- a/src/roster.py +++ b/src/roster.py @@ -18,6 +18,30 @@ from contact import Contact from sleekxmpp.xmlstream.stanzabase import JID from sleekxmpp.exceptions import IqError + +def sort_group_name(group): + return group.name.lower() + +def sort_group_folded(group): + return group.folded + +def sort_group_connected(group): + return - group.get_nb_connected_contacts() + +def sort_group_size(group): + return - len(group) + +def sort_group_none(group): + return 0 if group.name != 'none' else 1 + +GROUP_SORTING_METHODS = { + 'name': sort_group_name, + 'fold': sort_group_folded, + 'connected': sort_group_connected, + 'size': sort_group_size, + 'none': sort_group_none, +} + class Roster(object): """ The proxy class to get the roster from SleekXMPP. @@ -93,9 +117,17 @@ class Roster(object): """Set the SleekXMPP RosterSingle for our roster""" self.__node = value - def get_groups(self): + def get_groups(self, sort=''): """Return a list of the RosterGroups""" - return [group for group in self.groups.values() if group] + group_list = sorted(filter(lambda x: bool(x), self.groups.values()), key=lambda x: x.name.lower()) + + for sorting in sort.split('_'): + if sorting == 'reverse': + group_list = list(reversed(group_list)) + else: + method = GROUP_SORTING_METHODS.get(sorting, lambda x: 0) + group_list = sorted(group_list, key=method) + return group_list def get_group(self, name): """Return a group or create it if not present""" @@ -273,16 +305,16 @@ class RosterGroup(object): """Return the group contacts, filtered and sorted""" contact_list = self.contacts.copy() if not contact_filter\ else [contact for contact in self.contacts.copy() if contact_filter[0](contact, contact_filter[1])] + contact_list = sorted(contact_list, key=SORTING_METHODS['name']) for sorting in sort.split('_'): - method = SORTING_METHODS.get(sorting, lambda x: 0) if sorting == 'reverse': contact_list = list(reversed(contact_list)) else: + method = SORTING_METHODS.get(sorting, lambda x: 0) contact_list = sorted(contact_list, key=method) return contact_list - def toggle_folded(self): """Fold/unfold the group in the roster""" self.folded = not self.folded @@ -295,7 +327,7 @@ class RosterGroup(object): def get_nb_connected_contacts(self): """Return the number of connected contacts""" - return len([1 for contact in self.contacts if contact.resources]) + return len([1 for contact in self.contacts if len(contact)]) # Shared roster object diff --git a/src/windows.py b/src/windows.py index da80c989..4da0cff6 100644 --- a/src/windows.py +++ b/src/windows.py @@ -1610,7 +1610,8 @@ class RosterWin(Win): y = 1 show_offline = config.get('roster_show_offline', 'false') == 'true' sort = config.get('roster_sort', 'jid_show') or 'jid_show' - for group in roster.get_groups()[:]: + group_sort = config.get('roster_group_sort', 'name') or 'name' + for group in roster.get_groups(group_sort): contacts_filtered = group.get_contacts(roster.contact_filter) if (not show_offline and group.get_nb_connected_contacts() == 0) or not contacts_filtered: continue # Ignore empty groups -- cgit v1.2.3