summaryrefslogtreecommitdiff
path: root/src/roster.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/roster.py')
-rw-r--r--src/roster.py334
1 files changed, 0 insertions, 334 deletions
diff --git a/src/roster.py b/src/roster.py
deleted file mode 100644
index ba7da63e..00000000
--- a/src/roster.py
+++ /dev/null
@@ -1,334 +0,0 @@
-# Copyright 2010-2011 Florent Le Coz <louiz@louiz.org>
-#
-# This file is part of Poezio.
-#
-# Poezio is free software: you can redistribute it and/or modify
-# it under the terms of the zlib license. See the COPYING file.
-
-
-"""
-Defines the Roster and RosterGroup classes
-"""
-import logging
-log = logging.getLogger(__name__)
-
-from config import config
-from contact import Contact
-from roster_sorting import SORTING_METHODS, GROUP_SORTING_METHODS
-
-from os import path as p
-from datetime import datetime
-from common import safeJID
-from slixmpp.exceptions import IqError, IqTimeout
-
-
-class Roster(object):
- """
- The proxy class to get the roster from slixmpp.
- Caches Contact and RosterGroup objects.
- """
-
- def __init__(self):
- """
- node: the RosterSingle from slixmpp
- """
- self.__node = None
- self.contact_filter = None # A tuple(function, *args)
- # function to filter contacts,
- # on search, for example
- self.folded_groups = set(config.get('folded_roster_groups',
- section='var').split(':'))
- self.groups = {}
- self.contacts = {}
- self.length = 0
- self.connected = 0
-
- # Used for caching roster infos
- self.last_built = datetime.now()
- self.last_modified = datetime.now()
-
- def modified(self):
- self.last_modified = datetime.now()
-
- @property
- def needs_rebuild(self):
- return self.last_modified >= self.last_built
-
- def __getitem__(self, key):
- """Get a Contact from his bare JID"""
- key = safeJID(key).bare
- if key in self.contacts and self.contacts[key] is not None:
- return self.contacts[key]
- if key in self.jids():
- contact = Contact(self.__node[key])
- self.contacts[key] = contact
- return contact
-
- def __setitem__(self, key, value):
- """Set the a Contact value for the bare jid key"""
- self.contacts[key] = value
-
- def remove(self, jid):
- """Send a removal iq to the server"""
- jid = safeJID(jid).bare
- if self.__node[jid]:
- try:
- self.__node[jid].send_presence(ptype='unavailable')
- self.__node.remove(jid)
- except (IqError, IqTimeout):
- log.debug('IqError when removing %s:', jid, exc_info=True)
-
- def __delitem__(self, jid):
- """Remove a contact from the roster view"""
- jid = safeJID(jid).bare
- contact = self[jid]
- if not contact:
- return
- del self.contacts[contact.bare_jid]
-
- for group in list(self.groups.values()):
- group.remove(contact)
- if not group:
- del self.groups[group.name]
- self.modified()
-
- def __iter__(self):
- """Iterate over the jids of the contacts"""
- return iter(self.contacts.values())
-
- def __contains__(self, key):
- """True if the bare jid is in the roster, false otherwise"""
- return safeJID(key).bare in self.jids()
-
- @property
- def jid(self):
- """Our JID"""
- return self.__node.jid
-
- def get_and_set(self, jid):
- contact = self.contacts.get(jid)
- if contact is None:
- contact = Contact(self.__node[jid])
- self.contacts[jid] = contact
- return contact
- return contact
-
- def set_node(self, value):
- """Set the slixmpp RosterSingle for our roster"""
- self.__node = value
-
- def get_groups(self, sort=''):
- """Return a list of the RosterGroups"""
- group_list = sorted(
- (group for group in self.groups.values() if group),
- key=lambda x: x.name.lower() if x.name else ''
- )
-
- 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"""
- if name in self.groups:
- return self.groups[name]
- self.groups[name] = RosterGroup(name, folded=name in self.folded_groups)
-
- def add(self, jid):
- """Subscribe to a jid"""
- self.__node.subscribe(jid)
-
- def jids(self):
- """List of the contact JIDS"""
- l = []
- for key in self.__node.keys():
- contact = self.get_and_set(key)
- if key != self.jid and (contact and self.exists(contact)):
- l.append(key)
- self.update_size(l)
- return l
-
- def update_size(self, jids=None):
- if jids is None:
- jids = self.jids()
- self.length = len(jids)
-
- def get_contacts(self):
- """
- Return a list of all the contacts
- """
- return [self[jid] for jid in self.jids()]
-
- def get_contacts_sorted_filtered(self, sort=''):
- """
- Return a list of all the contacts sorted with a criteria
- """
- contact_list = []
- for contact in self.get_contacts():
- if contact.bare_jid != self.jid:
- if self.contact_filter:
- if self.contact_filter[0](contact, self.contact_filter[1]):
- contact_list.append(contact)
- else:
- contact_list.append(contact)
- contact_list = sorted(contact_list, key=SORTING_METHODS['name'])
-
- for sorting in sort.split(':'):
- 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 save_to_config_file(self):
- """
- Save various information to the config file
- e.g. the folded groups
- """
- folded_groups = ':'.join([group.name for group in self.groups.values()\
- if group.folded])
- log.debug('folded:%s\n', folded_groups)
- return config.silent_set('folded_roster_groups', folded_groups, 'var')
-
- def get_nb_connected_contacts(self):
- """
- Get the number of connected contacts
- """
- return self.connected
-
- def update_contact_groups(self, contact):
- """Regenerate the RosterGroups when receiving a contact update"""
- if not isinstance(contact, Contact):
- contact = self.get_and_set(contact)
- if not contact:
- return
- for name, group in self.groups.items():
- if name in contact.groups and contact not in group:
- group.add(contact)
- elif contact in group and name not in contact.groups:
- group.remove(contact)
-
- for group in contact.groups:
- if not group in self.groups:
- self.groups[group] = RosterGroup(group, folded=group in self.folded_groups)
- self.groups[group].add(contact)
-
- def __len__(self):
- """
- Return the number of contacts
- (used to return the display size, but now we have
- the display cache in RosterWin for that)
- """
- return self.length
-
- def __repr__(self):
- ret = '== Roster:\nContacts:\n'
- for contact in self.contacts.values():
- ret += '%s\n' % (contact,)
- ret += 'Groups\n'
- for group in self.groups:
- ret += '%s\n' % (group,)
- return ret + '\n'
-
- def export(self, path):
- """Export a list of bare jids to a given file"""
- if p.isfile(path):
- return
- try:
- f = open(path, 'w+', encoding='utf-8')
- f.writelines([str(i) + "\n" for i in self.contacts if self[i] and (self[i].subscription == "both" or self[i].ask)])
- f.close()
- return True
- except IOError:
- return
- except OSError:
- return
-
- def exists(self, contact):
- if not contact:
- return False
- for group in contact.groups:
- if contact not in self.groups.get(group, tuple()):
- return False
- return True
-
-
-class RosterGroup(object):
- """
- A RosterGroup is a group containing contacts
- It can be Friends/Family etc, but also can be
- Online/Offline or whatever
- """
- def __init__(self, name, contacts=None, folded=False):
- if not contacts:
- contacts = []
- self.contacts = set(contacts)
- self.name = name if name is not None else ''
- self.folded = folded # if the group content is to be shown
-
- def __iter__(self):
- """Iterate over the contacts"""
- return iter(self.contacts)
-
- def __repr__(self):
- return '<Roster_group: %s; %s>' % (self.name, self.contacts)
-
- def __len__(self):
- """Number of contacts in the group"""
- return len(self.contacts)
-
- def __contains__(self, contact):
- """
- Return a bool, telling if the contact is in the group
- """
- return contact in self.contacts
-
- def add(self, contact):
- """Add a contact to the group"""
- self.contacts.add(contact)
-
- def remove(self, contact):
- """Remove a contact from the group if present"""
- if contact in self.contacts:
- self.contacts.remove(contact)
-
- def get_contacts(self, contact_filter=None, sort=''):
- """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(':'):
- 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
- if self.folded:
- if self.name not in roster.folded_groups:
- roster.folded_groups.add(self.name)
- else:
- if self.name in roster.folded_groups:
- roster.folded_groups.remove(self.name)
-
- def get_nb_connected_contacts(self):
- """Return the number of connected contacts"""
- return len([1 for contact in self.contacts if len(contact)])
-
-def create_roster():
- "Create the global roster object"
- global roster
- roster = Roster()
-
-# Shared roster object
-roster = None