# Path: xclib/ejabberdctl.py
# class ejabberdctl:
#     def __init__(self, ctx):
#         self.ctx = ctx
# 
#     def execute(self, args):
#         logging.debug(self.ctx.ejabberdctl_path + str(args))
#         try:
#             return unutf8(subprocess.check_output([self.ctx.ejabberdctl_path] + args))
#         except subprocess.CalledProcessError as err:
#             return None
#             logging.warn('ejabberdctl failed with %s'
#                 % str(err))
#             return None
# 
#     def members(self, group, domain):
#         membership = self.execute(['srg_get_members', group, domain])
#         if membership is None:
#             membership = ()
#         else:
#             membership = membership.split('\n')
#         # Delete empty values (e.g. from empty output)
#         mem = []
#         for m in membership:
#             if m != '':
#                 mem.append(m)
#         logging.debug('%s@%s members: %s' % (group, domain, mem))
#         return mem
# 
# Path: xclib/utf8.py
# def utf8(u, opts='strict'):
#     return u.encode('utf-8', opts)
# 
# def unutf8(u, opts='strict'):
#     if opts == 'illegal':
#         try:
#             return u.decode('utf-8', 'strict')
#         except UnicodeError:
#             dec = u.decode('utf-8', 'ignore')
#             logging.error('Illegal UTF-8 sequence: %r' % dec)
#             sys.stderr.write('Illegal UTF-8 sequence: %r\n' % dec)
#             traceback.print_exc()
#             return 'illegal-utf8-sequence-' + dec
#     else:
#         return u.decode('utf-8', opts)
# 
# def utf8l(l):
#     '''Encode a copy of the list, converted to UTF-8'''
#     return list(map(utf8, l))


import logging
import traceback
import unicodedata
import sys
import time
from xclib.ejabberdctl import ejabberdctl
from xclib.utf8 import utf8, unutf8, utf8l
                        'SELECT fullname FROM rosterinfo WHERE jid=?',
                        (jid,)):
                    cached_name = row['fullname']
                logging.debug('cached_name = %s' % (cached_name,))
                if cached_name != desc['name']:
                    self.ctx.db.conn.begin()
                    self.ctx.db.conn.execute(
                            '''INSERT OR IGNORE INTO rosterinfo (jid)
                            VALUES (?)''', (jid,))
                    self.ctx.db.conn.execute(
                            '''UPDATE rosterinfo
                            SET fullname = ?
                            WHERE jid = ?''', (desc['name'], jid))
                    self.ctx.db.conn.commit()
                    logging.debug('set_vcard')
                    e.execute(['set_vcard', lhs, rhs, 'FN', desc['name']])
                    commands.append(('set_vcard', jid, desc['name']))
        return groups, commands

    def roster_update_groups(self, e, groups):
        '''Update shared roster groups with ejabberdctl

For all the *groups* we have information about:
- create the group (idempotent)
- delete the users that we do not know about anymore (idempotent)
- add the users we know about (idempotent)'''
        commands = []
        cleanname = {}
        loginjid = '@'.join((self.username, self.domain))
        logingroups = []

# Path: xclib/ejabberdctl.py
# class ejabberdctl:
#     def __init__(self, ctx):
#         self.ctx = ctx
# 
#     def execute(self, args):
#         logging.debug(self.ctx.ejabberdctl_path + str(args))
#         try:
#             return unutf8(subprocess.check_output([self.ctx.ejabberdctl_path] + args))
#         except subprocess.CalledProcessError as err:
#             return None
#             logging.warn('ejabberdctl failed with %s'
#                 % str(err))
#             return None
# 
#     def members(self, group, domain):
#         membership = self.execute(['srg_get_members', group, domain])
#         if membership is None:
#             membership = ()
#         else:
#             membership = membership.split('\n')
#         # Delete empty values (e.g. from empty output)
#         mem = []
#         for m in membership:
#             if m != '':
#                 mem.append(m)
#         logging.debug('%s@%s members: %s' % (group, domain, mem))
#         return mem
# 
# Path: xclib/utf8.py
# def utf8(u, opts='strict'):
#     return u.encode('utf-8', opts)
# 
# def unutf8(u, opts='strict'):
#     if opts == 'illegal':
#         try:
#             return u.decode('utf-8', 'strict')
#         except UnicodeError:
#             dec = u.decode('utf-8', 'ignore')
#             logging.error('Illegal UTF-8 sequence: %r' % dec)
#             sys.stderr.write('Illegal UTF-8 sequence: %r\n' % dec)
#             traceback.print_exc()
#             return 'illegal-utf8-sequence-' + dec
#     else:
#         return u.decode('utf-8', opts)
# 
# def utf8l(l):
#     '''Encode a copy of the list, converted to UTF-8'''
#     return list(map(utf8, l))


# Path: xclib/roster_thread.py
import logging
import traceback
import unicodedata
import sys
import time
from xclib.ejabberdctl import ejabberdctl
from xclib.utf8 import utf8, unutf8, utf8l

                        'SELECT fullname FROM rosterinfo WHERE jid=?',
                        (jid,)):
                    cached_name = row['fullname']
                logging.debug('cached_name = %s' % (cached_name,))
                if cached_name != desc['name']:
                    self.ctx.db.conn.begin()
                    self.ctx.db.conn.execute(
                            '''INSERT OR IGNORE INTO rosterinfo (jid)
                            VALUES (?)''', (jid,))
                    self.ctx.db.conn.execute(
                            '''UPDATE rosterinfo
                            SET fullname = ?
                            WHERE jid = ?''', (desc['name'], jid))
                    self.ctx.db.conn.commit()
                    logging.debug('set_vcard')
                    e.execute(['set_vcard', lhs, rhs, 'FN', desc['name']])
                    commands.append(('set_vcard', jid, desc['name']))
        return groups, commands

    def roster_update_groups(self, e, groups):
        '''Update shared roster groups with ejabberdctl

For all the *groups* we have information about:
- create the group (idempotent)
- delete the users that we do not know about anymore (idempotent)
- add the users we know about (idempotent)'''
        commands = []
        cleanname = {}
        loginjid = '@'.join((self.username, self.domain))
        logingroups = []

        for g in groups: