Beispiel #1
0
 def gotonline(self, presence):
     try:
         from_jid = sleekxmpp.JID(presence['from']).bare
         if misc.check_time(self, misc.data['stop'], from_jid) and misc.check_time(self, misc.data['quiet'], from_jid):
             self.send_presence(pto=presence['from'], pshow='', pnick=config.group_nick, pstatus=config.group_topic)
         else:
             self.send_presence(pto=presence['from'], pshow='dnd', pnick=config.group_nick, pstatus=config.group_topic)
         client_resource = sleekxmpp.JID(presence['from']).resource
         if client_resource.startswith('Talk.v') and client_resource[6:9] > '104':
             self.send_message(mto=presence['from'], mbody=_('Warning: You are probably using GTalk v%s version, which sends your data unsecurely. Please consider downgrading it to GTalk v104 or try third-party clients such as Pidgin.') % client_resource[6:9], mtype='chat')
     except Exception:
         pass
Beispiel #2
0
    def _validate(self, context):
        """
        Component validated
        """
        # Ensure we do not provide the service at first
        self._controller = False

        # Compute the MUC domain
        self._muc_domain = sleekxmpp.JID(self._room).domain

        # Register to session events
        self._bot.add_event_handler("session_start", self.__on_start)
        self._bot.add_event_handler("session_end", self.__on_end)
        self._bot.add_event_handler("muc::{0}::got_online".format(self._room),
                                    self.__room_in)
        self._bot.add_event_handler("muc::{0}::got_offline".format(self._room),
                                    self.__room_out)

        # Register "XEP-0203: Delayed Delivery" plug-in
        self._bot.register_plugin("xep_0203")

        # Register to messages (loop back filtered by the bot)
        self._bot.set_message_callback(self.__on_message)

        # Connect to the server
        self._bot.connect(self._host, self._port, use_tls=False)
Beispiel #3
0
def exec(bot = False, msg = None, ReplyTo = None, auth = None, **kwargs):

    if not bot or not msg:
        return False

    #проверим пришли ли параметры
    if "param" in kwargs:
        param_list = kwargs['param']
    else:
        param_list = ()

    if param_list:
        #есть параметры. Первым должно быть имя чата
        room = param_list[0]
        message = ' '.join(param_list[1:])
        toJID = sleekxmpp.JID(room + '@conference.jb.legionofdeath.ru')
        if message:
            reply = bot.make_message(toJID, message, mtype='groupchat')
            reply.send()

        #отчитаемся
        if not ReplyTo:
            reply = bot.make_message(msg['from'])
        else:
            reply = bot.make_message(ReplyTo)

        if message:
            reply['body'] = 'Сообщение отправлено в комнату ' + room
        else:
            reply['body'] = 'Пустые сообщения не отправляю.'
        reply['type'] = msg['type']
        reply.send()

    return True
Beispiel #4
0
    def report(self, msg, body):
        if msg['mucroom']:
            ReplyTo = sleekxmpp.JID(msg['mucroom'])
        else:
            ReplyTo = msg['from']

        reply = self.make_message(ReplyTo, body, mtype=msg['type'])
        reply.send()
Beispiel #5
0
    def _create_new_bot(self):
        """
        Really (re)creates a new XMPP bot object
        """
        # Clear & Start the thread pool
        self.__pool.clear()
        self.__pool.start()

        # Prepare the peer contact handler
        self.__contact = peer_contact.PeerContact(self._directory, None,
                                                  __name__ + ".contact")

        if self._username:
            # Generate the bot full JID: resource is set to be peer's UUID
            bot_jid = sleekxmpp.JID(self._username)
            bot_jid.resource = self._directory.local_uid
        else:
            # Anonymous login
            bot_jid = None

        # Create the bot
        self._bot = HeraldBot(bot_jid, self._password,
                              self._directory.local_uid)

        # Avoids bot's auto reconnection.
        # when disconnected event is captured,
        # we destroy the old bot and re-create a new one.
        self._bot.auto_reconnect = False

        # This avoids to wait too long between initial reattempts, i.e. if
        # the first server addresses (DNS records) aren't responding
        self._bot.reconnect_max_delay = 5

        # Register to session events
        self._bot.add_event_handler("session_start", self._on_session_start)
        self._bot.add_event_handler("failed_auth", self._on_failed_auth)
        self._bot.add_event_handler("session_end", self._on_session_end)
        self._bot.add_event_handler("disconnected", self._on_disconnected)

        # Register the Multi-User Chat plug-in
        self._bot.register_plugin('xep_0045')

        # Register "XEP-0203: Delayed Delivery" plug-in
        self._bot.register_plugin("xep_0203")

        # Register to messages (loop back filtered by the bot)
        self._bot.set_message_callback(self.__on_message)

        # Connect to the server
        # set reattempt to True to try to reconnect to the server in case of
        # network problems or address errors.
        if not self._bot.connect(self._host, self._port, reattempt=True):
            _logger.error("Can't connect to the XMPP server at %s port %s",
                          self._host, self._port)
Beispiel #6
0
def getnick(xmpp, nick_or_jid):
    if nick_or_jid in nick_table:
        return nick_or_jid
    elif isjidvalid(nick_or_jid) and nick_or_jid in xmpp.client_roster and xmpp.client_roster[nick_or_jid]['to']:
        nick = xmpp.client_roster[nick_or_jid]['name']
        if nick:
            return nick
        else:
            return sleekxmpp.JID(nick_or_jid).user
    else:
        return None
Beispiel #7
0
 def unsubscribe(self, presence):
     from_jid = sleekxmpp.JID(presence['from']).bare
     if from_jid in misc.data['stop'][from_jid]:
         del misc.data['stop'][from_jid]
         misc.save_data()
     from_nick = misc.getnick(self, from_jid)
     try:
         self.del_roster_item(from_jid)
     except Exception:
         pass
     sys.stderr.write('%s unsubscribed me.\n' % presence['from'])
     self.send_except(from_jid, _('%s has quited this group.') % from_nick)
Beispiel #8
0
 def subscribed(self, presence):
     jid = sleekxmpp.JID(presence['from']).bare
     sys.stderr.write('I subcribed %s.\n' % presence['from'])
     while True:
         to_nick = int(random.random() * 90000 + 10000)
         if not misc.getnick(self, to_nick):
             break
         to_nick += 1
     to_nick = 'Guest' + str(to_nick)
     self.update_roster(jid, name=to_nick)
     misc.add_nicktable(self, jid)
     self.send_message(mto=presence['from'], mbody=misc.replace_prefix(config.welcome_message, config.command_prefix[0]), mtype='chat')
     self.send_message(mto=presence['from'], mbody=misc.replace_prefix(_('You have been given a random nickname %s, please use /-nick to change your nickname.'), config.command_prefix[0]) % to_nick, mtype='chat')
     self.send_message(mto=presence['from'], mbody=misc.replace_prefix(_('For more help, type /-help'), config.command_prefix[0]), mtype='chat')
     self.send_except(jid, _('%s has joined this group.') % to_nick)
     self.send_presence(pto=jid, pshow='', pnick=config.group_nick, pstatus=config.group_topic)
Beispiel #9
0
def exec(bot=False, msg=None, ReplyTo=None, auth=None, **kwargs):

    if not bot or not msg:
        return False

    #проверим пришли ли параметры
    if "param" in kwargs:
        param_list = kwargs['param']
    else:
        param_list = ()

    if param_list:
        #есть параметры. нас интересует только первый
        name = param_list[0] + '@jb.legionofdeath.ru'
        try:
            result = bot.plugin['xep_0012'].get_last_activity(name)
            seconds = int(result['last_activity']['seconds'])
            if seconds == 0:
                textline = 'Пользователь ' + name + ' сейчас онлайн.'
                JID = sleekxmpp.JID(name)
                notify = bot.make_message(JID)
                notify['body'] = 'Тебя разыскивает ' + bot.JID_to_realJID(
                    msg).bare
                notify['type'] = 'Normal'
                notify.send()
            else:
                textline = 'Пользователь ' + name + ' был онлайн ' + bot.one_day_delta_to_str(
                    seconds) + '.'
        except IqError as err:
            textline = 'Ошибка при получении данных о ' + name
        except:
            pass

    else:
        textline = 'Не задано имя'

    if not ReplyTo:
        reply = bot.make_message(msg['from'])
    else:
        reply = bot.make_message(ReplyTo)

    reply['body'] = textline
    reply['type'] = msg['type']
    reply.send()

    return True
Beispiel #10
0
    def room_jid(self, room_name):
        """
        Prepares a JID object for the given room in the current MUC domain

        :param room_name: The short name of a room
        :return: A JID object
        """
        if self.__muc_service == "groupchat.google.com":
            # Special case: Google Talk requires a specific room name format
            # Make a MD5 hash of the full room name
            app_id = self._directory.get_local_peer().app_id
            full_name = "cohorte-{0}-{1}".format(app_id, room_name)
            md5 = hashlib.md5(to_bytes(full_name)).hexdigest()

            # Format the room name to be Google Talk-compatible
            room_name = "private-chat-{0}".format(str(uuid.UUID(md5)))

        return sleekxmpp.JID(local=room_name, domain=self.__muc_service)
Beispiel #11
0
    def create_room(self,
                    room,
                    service,
                    nick,
                    config=None,
                    callback=None,
                    errback=None):
        """
        Prepares the creation of a room.

        The callback is a method with two arguments:
          - room: Bare JID of the room
          - nick: Nick used to create the room

        The errback is a method with 4 arguments:
          - room: Bare JID of the room
          - nick: Nick used to create the room
          - condition: error category (XMPP specification or "not-owner")
          - text: description of the error


        :param room: Name of the room
        :param service: Name of the XMPP MUC service
        :param config: Configuration of the room
        :param callback: Method called back on success
        :param errback: Method called on error
        """
        self.__logger.info("Creating room: %s", room)

        with self.__lock:
            # Format the room JID
            room_jid = sleekxmpp.JID(local=room, domain=service).bare

            if not self.__rooms:
                # First room to create: register to events
                self.__xmpp.add_event_handler("presence", self.__on_presence)

            # Store information
            self.__rooms[room_jid] = RoomData(room_jid, nick, config, callback,
                                              errback)

        # Send the presence, i.e. request creation of the room
        self.__muc.joinMUC(room_jid, nick)
Beispiel #12
0
    def fire_group(self, group, peers, message):
        """
        Fires a message to a group of peers

        :param group: Name of a group
        :param peers: Peers to communicate with
        :param message: Message to send
        :return: The list of reached peers
        """
        # Special case for the main room
        if group == 'all':
            group_jid = self._room
        else:
            # Get the group JID
            group_jid = sleekxmpp.JID(local=group, domain=self._muc_domain)

        # Send the XMPP message
        self.__send_message("groupchat", group_jid, message)
        return peers
Beispiel #13
0
    def check_nick(self, presence):

        if not self.censor:
            return

        if presence['muc']['nick'] != self.mucnick:
            jid = presence['muc']['jid'].bare
            module = getattr(self.plugins['storage'], 'muc_censor')
            correct_name = module.exec(bot=self,
                                       msg=None,
                                       ReplyTo=None,
                                       auth=None,
                                       param=(jid, ))
            if correct_name and correct_name != presence['muc']['nick']:
                #ругаемся что ник надо поправить
                ReplyTo = sleekxmpp.JID(presence['muc']['room'])
                reply = self.make_message(ReplyTo)
                reply['body'] = '' + presence['muc'][
                    'nick'] + ' поменяй ник на ' + correct_name + '\nЕсли считаешь что ник корректный, обнови API ключ на http://dashboard.legionofdeath.ru'
                reply['type'] = 'groupchat'
                reply.send()
                #пробуем насильно поменять ник
                stanza = self.makePresence()
                x = ET.Element('{http://jabber.org/protocol/muc#user}x')
                itemXML = ET.Element(
                    'item', {
                        'affiliation': 'owner',
                        'jid': presence['muc']['jid'].full,
                        'role': 'moderator'
                    })
                x.append(itemXML)
                itemXML = ET.Element('status ', {
                    'code': '110',
                })
                x.append(itemXML)
                itemXML = ET.Element('status ', {
                    'code': '210',
                })
                x.append(itemXML)
                stanza.append(x)
Beispiel #14
0
    def form_message(self, msg):

        if msg['form']['type'] == 'submit':
            #не нашел способа узнать что за форма, проверяю по наличию поля в форме
            if "Broadcast" in msg['form']['values']:

                items = msg['form']['values']['Group'].split(';')
                for item in items:
                    toJID = sleekxmpp.JID(jid=item +
                                          '@broadcast.jb.legionofdeath.ru')
                    #toJID = sleekxmpp.JID('*****@*****.**')

                    reply = self.make_message(
                        toJID,
                        'Broadcast from ' + self.JID_to_realJID(msg).bare +
                        ' to ' + item + '\n' +
                        msg['form']['values']['Broadcast'],
                        mtype='normal')
                    #reply = self.make_message(toJID, 'fgh', mtype='normal')
                    reply.send()

                #отчитаемся о посылке бродкаста
                self.report(
                    msg,
                    'Сделан бродкаст группе ' + msg['form']['values']['Group'])
            elif "GroupContent" in msg['form']['values']:

                group = msg['form']['values']['Group']
                group_content = msg['form']['values']['GroupContent']
                group_db = self.bases['group_db']
                #если контент пустой, группу надо удалить
                if group_content:
                    group_db.set_value_by_ID(group, group_content)
                    self.report(
                        msg, "Group " + group + " now set to <" +
                        group_content + ">")
                else:
                    group_db._db_base.__delitem__(group)
                    self.report(msg, "Group " + group + " now deleted")
Beispiel #15
0
    def cron(self, **kwargs):

        if "plugin" in kwargs:
            plugin = kwargs['plugin']
        else:
            return
        module = getattr(self.plugins['storage'], plugin)
        body = module.exec(bot=self,
                           msg=None,
                           ReplyTo=None,
                           auth=None,
                           param=None)

        #получим список комнат куда спамить
        try:
            rooms = module.rooms()
            allrooms = False
        except:
            allrooms = True

        if not body:
            return
        body = '\n' + '*' * 40 + '\n' + body + '\n' + '*' * 40
        #бежим по комнатам где сидим
        for room in self.plugin['xep_0045'].rooms:
            #print(allrooms)
            #print(rooms)
            if room == self.botroom + '@conference.jb.legionofdeath.ru':
                continue

            if not allrooms:
                if not room in rooms:
                    continue

            ReplyTo = sleekxmpp.JID(room)
            reply = self.make_message(ReplyTo)
            reply['body'] = body
            reply['type'] = 'groupchat'
            reply.send()
Beispiel #16
0
    else:
        logging.basicConfig(level=logging.INFO)
        logging.getLogger("sleekxmpp").setLevel(logging.WARNING)

    if not args.server and not args.jid:
        _logger.error("No JID nor server given. Abandon.")
        sys.exit(1)

    # Get the password if necessary
    _password = args.password
    if args.jid and not args.password:
        try:
            import getpass
        except ImportError:
            _logger.error("getpass() unavailable: give a password in "
                          "command line")
        else:
            try:
                _password = getpass.getpass()
            except getpass.GetPassWarning:
                pass

    # Get the server from the JID, if necessary
    _server = args.server
    if not _server:
        import sleekxmpp
        _server = sleekxmpp.JID(args.jid).domain

    # Run the entry point
    main(_server, args.port, args.jid, _password, args.use_tls, args.use_ssl)
Beispiel #17
0
def main(argv=None):
    """
    Entry point

    :param argv: Script arguments (None for sys.argv)
    :return: An exit code or None
    """
    # Prepare arguments
    parser = argparse.ArgumentParser(prog="pelix.shell.xmpp",
                                     parents=[make_common_parser()],
                                     description="Pelix XMPP Shell")

    group = parser.add_argument_group("XMPP options")
    group.add_argument("-j", "--jid", dest="jid", help="Jabber ID")
    group.add_argument("--password", dest="password", help="JID password")
    group.add_argument("-s",
                       "--server",
                       dest="server",
                       help="XMPP server host")
    group.add_argument("-p",
                       "--port",
                       dest="port",
                       type=int,
                       default=5222,
                       help="XMPP server port")
    group.add_argument("--tls",
                       dest="use_tls",
                       action="store_true",
                       help="Use a STARTTLS connection")
    group.add_argument("--ssl",
                       dest="use_ssl",
                       action="store_true",
                       help="Use an SSL connection")

    # Parse them
    args = parser.parse_args(argv)

    # Handle common arguments
    init = handle_common_arguments(args)

    # Quiet down the SleekXMPP logger
    if not args.verbose:
        logging.getLogger("sleekxmpp").setLevel(logging.WARNING)

    if not args.server and not args.jid:
        _logger.error("No JID nor server given. Abandon.")
        sys.exit(1)

    # Get the password if necessary
    password = args.password
    if args.jid and args.password is None:
        try:
            import getpass
        except ImportError:
            _logger.error(
                "getpass() unavailable: give a password in command line")
        else:
            try:
                password = getpass.getpass()
            except getpass.GetPassWarning:
                pass

    # Get the server from the JID, if necessary
    server = args.server
    if not server:
        server = sleekxmpp.JID(args.jid).domain

    # Set the initial bundles
    bundles = [
        'pelix.ipopo.core', 'pelix.shell.core', 'pelix.shell.ipopo',
        'pelix.shell.console', 'pelix.shell.xmpp'
    ]
    bundles.extend(init.bundles)

    # Use the utility method to create, run and delete the framework
    framework = pelix.framework.create_framework(remove_duplicates(bundles),
                                                 init.properties)
    framework.start()

    # Instantiate a Remote Shell
    with use_ipopo(framework.get_bundle_context()) as ipopo:
        ipopo.instantiate(
            pelix.shell.FACTORY_XMPP_SHELL, "xmpp-shell", {
                "shell.xmpp.server": server,
                "shell.xmpp.port": args.port,
                "shell.xmpp.jid": args.jid,
                "shell.xmpp.password": password,
                "shell.xmpp.tls": args.use_tls,
                "shell.xmpp.ssl": args.use_ssl
            })

    # Instantiate configured components
    init.instantiate_components(framework.get_bundle_context())

    try:
        framework.wait_for_stop()
    except KeyboardInterrupt:
        framework.stop()
Beispiel #18
0
def exec(bot=False, msg=None, ReplyTo=None, auth=None, **kwargs):

    if not bot or not msg:
        return False

    #проверим пришли ли параметры
    if "param" in kwargs:
        param_list = kwargs['param']
    else:
        param_list = ()

    if param_list:
        #есть параметры. Первым должно быть имя группы, все остальное текст сообщения
        group = param_list[0]
        #получим список групп
        group_db = bot.bases['group_db']
        item = group_db.get_value_by_ID(group).decode()

        bc_from = bot.JID_to_realJID(msg).bare
        bcmessage = ' '.join(param_list[1:])
        if item:
            items = item.split(';')
            for item in items:
                toJID = sleekxmpp.JID(jid=item +
                                      '@broadcast.jb.legionofdeath.ru')
                reply = bot.make_message(toJID,
                                         'Broadcast from ' + bc_from + ' to ' +
                                         group + '\n' + bcmessage,
                                         mtype='normal')
                reply.send()

            #отчитаемся
            if not ReplyTo:
                reply = bot.make_message(msg['from'])
            else:
                reply = bot.make_message(ReplyTo)
            reply['body'] = 'Сделан бродкаст группе ' + group
            reply['type'] = msg['type']
            reply.send()
        else:
            if not ReplyTo:
                reply = bot.make_message(msg['from'])
            else:
                reply = bot.make_message(ReplyTo)
            reply['body'] = "Group <" + group + "> not found"
            reply['type'] = msg['type']
            reply.send()

    else:
        #параметров не передали, откроем форму
        reply = bot.make_message(msg['from'], msubject='Broadcast')
        form = reply['form']

        fields = collections.OrderedDict()

        #получим список групп
        group_db = bot.bases['group_db']
        items = group_db.get_list()

        options = []
        for item in items:
            options.append({
                'label': item.decode(),
                'value': group_db.get_value_by_ID(item).decode()
            })
            #print(item + group_db.get_value_by_ID(item))
        fields['Group'] = {
            'type': 'list-single',
            'label': 'Group',
            'options': options
        }

        #'options': [{'label': 'test',
        #             'value': 'test'},
        #            {'label': 'Fleet Commanders',
        #             'value': 'Fleet Commanders'}]}

        fields['Broadcast'] = {
            'type': 'text-multi',
            'label': 'Broadcast',
            'value': 'New broadcast text\nhere'
        }

        form['fields'] = fields
        form['title'] = 'New broadcast'

        reply.send()

    return True
Beispiel #19
0
    def JID_to_realJID(self, msg):

        if msg['from'].full in self.dict_of_real_JID:
            return sleekxmpp.JID(self.dict_of_real_JID[msg['from'].full])
        else:
            return msg['from']
Beispiel #20
0
 def subscribe(self, presence):
     sys.stderr.write('%s subscribed me.\n' % presence['from'])
     self.send_presence(pto=sleekxmpp.JID(presence['from']).bare, pshow='away', pnick=config.group_nick, pstatus=_('Not accepted subscription yet'))
Beispiel #21
0
    def message(self, msg):
        """
        Process incoming message stanzas. Be aware that this also
        includes MUC messages and error messages. It is usually
        a good idea to check the messages's type before processing
        or sending replies.

        Arguments:
            msg -- The received message stanza. See the documentation
                   for stanza objects and the Message stanza to see
                   how it may be used.
        """
        #свои сообщения в групчатах сразу игнорим
        if msg['mucnick'] == self.nick or msg['mucnick'] == self.mucnick:
            return

        if msg['type'] in ('chat', 'normal', 'groupchat'):

            if 'die!' == msg['body']:
                self._disconnect()
            elif 'зло' == msg['body']:
                self.censor = True

            #получим первое слово сообщения
            temp_list = msg['body'].split(' ')
            command = temp_list[0]
            #проверим есть ли параметры
            param = None
            if len(temp_list) > 1:
                param = temp_list[1:]
            #будем сообщать о сообщениях боту в приват или о командах в конфах
            if msg['type'] in ('chat', 'normal') or (
                    msg['type'] == 'groupchat'
                    and command in self.plugins['commands']):
                ReplyTo = sleekxmpp.JID(self.botroom +
                                        '@conference.jb.legionofdeath.ru')
                reply = self.make_message(ReplyTo)
                if msg['type'] in ('chat', 'normal'):
                    textline = 'Личное сообщение от ' + msg[
                        'from'].full + '\n' + msg['body']
                else:
                    textline = 'Команда в комнате ' + msg[
                        'mucroom'] + ' от ' + msg[
                            'from'].resource + '\n' + msg['body']

                reply['body'] = textline
                reply['type'] = 'groupchat'
                reply.send()

            if command in self.plugins['commands']:
                module = getattr(self.plugins['storage'], command)
                #проверим команду на доступность всем
                try:
                    secret = module.secret()
                except:
                    secret = False

                #если сообщение из комнаты, заполним ReplyTo
                if msg['mucroom']:
                    ReplyTo = sleekxmpp.JID(msg['mucroom'])
                else:
                    ReplyTo = None

                admin = self.is_admin(self.JID_to_realJID(msg))

                if secret and admin:
                    module.exec(bot=self,
                                msg=msg,
                                ReplyTo=ReplyTo,
                                auth=None,
                                param=param)
                elif secret and (not admin):
                    msg.reply("Access denied to command \n%(body)s" %
                              msg).send()
                elif not secret:
                    module.exec(bot=self,
                                msg=msg,
                                ReplyTo=ReplyTo,
                                auth=None,
                                param=param)

            else:
                pass
                #if not msg['type'] == 'groupchat':
                #pass
                #msg.reply("Thanks for sending\n%(body)s" % msg).send()

        return
Beispiel #22
0
def trigger(xmpp, msg):
    try:
        from_jid = msg['from'].bare
        cmd = msg['body'][1:].split()
        cmd[0] = cmd[0].lower()
        prefix = msg['body'][0]
        if not cmd:
            return

        if cmd[0] in ('names', 'name', 'list', 'la'):
            cmd[0] = 'ls'
            cmd.append('-a')
        elif cmd[0] in ('users', 'user', 'dir', 'lla', 'lal'):
            cmd[0] = 'ls'
            cmd.append('-la')
        elif cmd[0] in ('online', 'll'):
            cmd[0] = 'ls'
            cmd.append('-l')
        elif cmd[0] in ('man', 'info'):
            cmd[0] = 'help'
        elif cmd[0] in ('stat', 'whowas', 'dig', 'nslookup'):
            cmd[0] = 'whois'
        elif cmd[0] in ('iam', 'whoami'):
            cmd = ['whois', from_jid]
        elif cmd[0] in ('pm', 'dm', 'query', 'tell'):
            cmd[0] = 'msg'
        elif cmd[0] in ('test', 'traceroute', 'tracert', 'pong'):
            cmd[0] = 'ping'
        elif cmd[0] in ('poweroff', 'halt'):
            cmd[0] = 'shutdown'
        elif cmd[0] in ('restart', 'reboot'):
            cmd[0] = 'shutdown'
            cmd.append('-r')
        elif cmd[0] in ('rm', 'del', 'remove', 'delete'):
            cmd[0] = 'kick'
        elif cmd[0] in ('nickname', 'alias'):
            cmd[0] = 'nick'
        elif cmd[0] in ('mv', 'move', 'ren', 'rename'):
            cmd[0] = 'setnick'
        elif cmd[0] == 'run':
            cmd[0] = 'system'
        elif cmd[0] == 'quote':
            cmd[0] = 'say'
        elif cmd[0] == 'action':
            cmd[0] = 'me'
        elif cmd[0] in ('pause', 'sleep', 'delay'):
            cmd[0] = 'stop'
        elif cmd[0] == 'on':
            cmd = ['stop', 'off']
        elif cmd[0] == 'off':
            cmd = ['stop', 'forever']
        elif cmd[0] in ('log', 'history', 'hist'):
            cmd[0] = 'old'
        elif cmd[0] == 'mute':
            cmd[0] = 'quiet'
        elif cmd[0] in ('part', 'leave', 'exit', 'bye'):
            cmd[0] = 'quit'
        elif cmd[0] == 'about':
            cmd = ['help', ':about']
        elif len(cmd[0]) > 4 and cmd[0].startswith('init'):
            cmd.insert(1, cmd[0][4:])
            cmd[0] = 'init'

        if cmd[0] == 'say':
            if len(cmd) < 2:
                msg.reply(
                    misc.replace_prefix(_('Error: /-say takes arguments.'),
                                        prefix)).send()
            elif misc.check_time(xmpp, misc.data['quiet'], from_jid):
                for l in msg['body'].split(None, 1)[1].splitlines():
                    xmpp.dispatch_message(from_jid, l)
            else:
                msg.reply(_('You have been quieted.')).send()
            return

        if cmd[0] == 'me':
            if len(cmd) < 2:
                msg.reply(
                    misc.replace_prefix(_('Error: /-me takes arguments.'),
                                        prefix)).send()
            elif misc.check_time(xmpp, misc.data['quiet'], from_jid):
                from_nick = misc.getnick(xmpp, from_jid)
                for l in msg['body'].split(None, 1)[1].splitlines():
                    xmpp.send_except(None, '* %s %s' % (from_nick, l))
            else:
                msg.reply(_('You have been quieted.')).send()
            return

        misc.cmd_log.append((time.time(), '%s: %s' % (from_jid, msg['body'])))
        if len(misc.cmd_log) > config.cmdlogsize:
            misc.cmd_log[len(misc.cmd_log) - config.cmdlogsize:] = []

        if cmd[0] == 'eval':
            if from_jid in config.root:
                if len(cmd) > 1:
                    msg.reply(str(eval(msg['body'].split(None, 1)[1]))).send()
                else:
                    msg.reply(
                        misc.replace_prefix(
                            _('Error: /-eval takes arguments.'),
                            prefix)).send()
            elif from_jid in config.admins:
                msg.reply(_('Error: Permission denied.')).send()
            else:
                msg.reply(
                    misc.replace_prefix(
                        _('Error: Unknown command. For help, type /-help'),
                        prefix)).send()
            return

        if cmd[0] == 'exec':
            if from_jid in config.root:
                if len(cmd) > 1:
                    exec(msg['body'].split(None, 1)[1])
                    msg.reply(_('Command executed.')).send()
                else:
                    msg.reply(
                        misc.replace_prefix(
                            _('Error: /-exec takes arguments.'),
                            prefix)).send()
            elif from_jid in config.admins:
                msg.reply(_('Error: Permission denied.')).send()
            else:
                msg.reply(
                    misc.replace_prefix(
                        _('Error: Unknown command. For help, type /-help'),
                        prefix)).send()
            return

        if cmd[0] == 'system':
            if from_jid in config.root:
                if len(cmd) > 1:
                    msg.reply('\n' +
                              subprocess.Popen(msg['body'].split(None, 1)[1],
                                               shell=True,
                                               stdout=subprocess.PIPE,
                                               stderr=subprocess.STDOUT,
                                               close_fds=True).communicate()[0]
                              .strip(b'\n').decode('utf-8', 'replace')).send()
                else:
                    msg.reply(
                        misc.replace_prefix(
                            _('Error: /-system takes arguments.'),
                            prefix)).send()
            elif from_jid in config.admins:
                msg.reply(_('Error: Permission denied.')).send()
            else:
                msg.reply(
                    misc.replace_prefix(
                        _('Error: Unknown command. For help, type /-help'),
                        prefix)).send()
            return

        if cmd[0] == 'msg':
            if len(cmd) > 2:
                isAdmin = from_jid in config.admins
                success = 0
                for to_jid in misc.find_users(xmpp, cmd[1], isAdmin):
                    success = 1
                    if isAdmin or to_jid not in misc.data[
                            'block'] or from_jid not in misc.data['block'][
                                to_jid]:
                        xmpp.send_message(
                            mto=to_jid,
                            mbody='%s (%s): %s' %
                            (misc.getnick(xmpp, from_jid), _('DM'),
                             msg['body'].split(None, 2)[2]),
                            mtype='chat')
                        success = 2
                    else:
                        xmpp.send_message(
                            mto=from_jid,
                            mbody=_('Error: %s has blocked your messages.') %
                            misc.getnick(xmpp, to_jid),
                            mtype='chat')
                if success == 2:
                    msg.reply(_('Your message has been sent.')).send()
                elif success == 0:
                    msg.reply(
                        _('Error: User %s is not a member of this group.') %
                        (cmd[1])).send()
            else:
                msg.reply(
                    misc.replace_prefix(
                        _('Error: /-msg takes exactly two arguments.'),
                        prefix)).send()
            return

        if cmd[0] == 'help':
            if len(cmd) < 2:
                cmd.append('main')
                if from_jid in config.admins:
                    cmd.append('admin')
            s = ''
            for i in cmd[1:]:
                i = i.lstrip(prefix)
                if i.startswith('-'):
                    continue
                if i in help_msg:
                    s += '\n\n' + misc.replace_prefix(help_msg[i],
                                                      prefix).strip('\n')
                elif ':' + i in help_msg:
                    s += '\n\n' + misc.replace_prefix(help_msg[':' + i],
                                                      prefix).strip('\n')
            if len(s) > 1:
                s = s[1:]
            else:
                s = _('Error: No help message for %s.') % cmd[1]
            msg.reply(s).send()
            return

        if not cmd[0].startswith(':') and cmd[0] in help_msg:
            for i in cmd[1:]:
                if i == '--help':
                    msg.reply('\n' + misc.replace_prefix(
                        help_msg[cmd[0]], prefix).strip('\n')).send()
                    return

        if cmd[0] == 'init':
            if len(cmd) == 2:
                if cmd[1] in ('S', 's'):
                    cmd[1] = 'single'
                if from_jid in config.admins:
                    xmpp.send_except(
                        None,
                        _('INIT: Switching to runlevel: %s') % cmd[1])
                else:
                    xmpp.send_message(
                        mto=from_jid,
                        mbody=_('INIT: Switching to runlevel: %s') % cmd[1],
                        mtype='chat')
                if cmd[1] == '0':
                    cmd[0] = 'shutdown'
                    del cmd[1]
                elif cmd[1] == '6':
                    cmd[0] = 'shutdown'
                    cmd[1] = '-r'
                else:
                    return
            elif len(cmd) == 1:
                msg.reply(
                    misc.replace_prefix(
                        _('Error: /-init must be run as PID 1.'),
                        prefix)).send()
                return
            else:
                msg.reply(
                    misc.replace_prefix(
                        _('Error: /-init takes exactly one argument.'),
                        perfix)).send()
                return

        if cmd[0] == 'quit':
            msg.reply(_('You have quited this group.')).send()
            if from_jid in misc.data['stop']:
                del misc.data['stop'][from_jid]
                misc.save_data()
            to_nick = misc.getnick(xmpp, from_jid)
            misc.del_nicktable(xmpp, from_jid)
            try:
                xmpp.del_roster_item(from_jid)
            except Exception:
                pass
            xmpp.send_except(from_jid,
                             _('%s has quited this group.') % to_nick)
            return

        if cmd[0] == 'old':
            from_log = misc.msg_log
            arg = []
            for i in cmd[1:]:
                if i.startswith('-'):
                    if 'c' in i:
                        if from_jid in config.admins:
                            from_log = misc.cmd_log
                        else:
                            msg.reply(_('Error: Permission denied.')).send()
                            return
                elif i:
                    arg.append(i)
            try:
                if len(arg) >= 1:
                    from_time = arg[0]
                    if len(arg) >= 2:
                        len_time = arg[1]
                    else:
                        len_time = from_time
                else:
                    from_time = '25'
                    len_time = from_time
                if from_time.isdigit():
                    from_time = int(from_time)
                else:
                    from_time = misc.TimeUnit(from_time)
                if len_time.isdigit():
                    len_time = int(len_time)
                else:
                    len_time = misc.TimeUnit(len_time)
            except ValueError:
                msg.reply(_('Error: Invalid time specification.')).send()
                return
            res = []
            nowtime = time.time()
            try:
                if isinstance(from_time, misc.TimeUnit):
                    res = from_log[bisect.bisect_left(from_log, (
                        nowtime - from_time, )):]
                    if isinstance(len_time, misc.TimeUnit):
                        res = res[:bisect.bisect(res, (nowtime - from_time +
                                                       len_time, ))]
                    else:
                        res = res[:len_time]
                else:
                    res = from_log[-from_time:]
                    if isinstance(len_time, misc.TimeUnit):
                        res = res[:bisect.bisect(res, (res[0][0] +
                                                       len_time, ))]
                    else:
                        res = res[:len_time]
                res = res[:100]
            except IndexError:
                pass
                raise
            if res:
                sres = ''
                sres += '\n' + _('Start:\t%s') % misc.lctime(res[0][0])
                for i in res:
                    sres += '\n(%s) %s' % (time.strftime(
                        "%T", time.localtime(i[0])), i[1])
                sres += '\n' + _('End:\t%s') % misc.lctime(res[-1][0])
                msg.reply(sres).send()
            else:
                msg.reply(_('No messages match your criteria.')).send()
            return

        if cmd[0] == 'stop':
            if len(cmd) > 1:
                to_time = ''.join(cmd[1:])
                try:
                    if to_time in ('ever', 'forever'):
                        misc.data['stop'][from_jid] = None
                        misc.save_data()
                    elif to_time in ('off', 'never'):
                        if from_jid in misc.data['stop']:
                            del misc.data['stop'][from_jid]
                            misc.save_data()
                            try:
                                if to_jid not in data[
                                        'stop'] and to_jid not in data['quiet']:
                                    xmpp.send_presence(
                                        pto=to_jid,
                                        pshow='',
                                        pnick=config.group_nick,
                                        pstatus=config.group_topic)
                            except Exception:
                                pass
                    else:
                        to_time = misc.TimeUnit(to_time)
                        if to_time > 0:
                            to_time = time.time() + misc.TimeUnit(to_time)
                            misc.data['stop'][from_jid] = to_time
                        elif from_jid in misc.data['stop']:
                            del misc.data['stop'][from_jid]
                            try:
                                if to_jid not in data[
                                        'stop'] and to_jid not in data['quiet']:
                                    xmpp.send_presence(
                                        pto=to_jid,
                                        pshow='',
                                        pnick=config.group_nick,
                                        pstatus=config.group_topic)
                            except Exception:
                                pass
                        misc.save_data()
                except ValueError:
                    msg.reply(_('Error: Invalid time specification.')).send()
                    return
            if not misc.check_time(xmpp, misc.data['stop'], from_jid):
                to_time = misc.data['stop'][from_jid]
                if to_time is None:
                    msg.reply(_('You will never receive messages.')).send()
                else:
                    msg.reply(
                        _('You will not receive messages until %s.') %
                        misc.lctime(to_time)).send()
                xmpp.send_presence(pto=from_jid,
                                   pshow='dnd',
                                   pnick=config.group_nick,
                                   pstatus=config.group_topic)
            else:
                msg.reply(_('You are currently receiving messages.')).send()
            return

        if cmd[0] == 'ping':
            if len(cmd) > 1:
                msg.reply('Pong: %s' % msg['body'].split(None, 1)[1]).send()
            else:
                msg.reply('Pong!').send()
            return

        if cmd[0] == 'shutdown':
            if from_jid in config.admins:
                misc.quiting = True
                quiet = False
                for i in cmd[1:]:
                    if i.startswith('-'):
                        if 'r' in i:
                            misc.restarting = True
                        if 'q' in i:
                            quiet = True
                if misc.restarting:
                    msg.reply(_('Restarting.')).send(now=True)
                    if not quiet:
                        xmpp.send_except(
                            from_jid,
                            _('Restarting by %s.') %
                            misc.getnick(xmpp, from_jid))
                    raise SystemExit
                elif from_jid in config.root:
                    msg.reply(_('Shutting down.')).send(now=True)
                    if not quiet:
                        xmpp.send_except(
                            from_jid,
                            _('Shutting down by %s.') %
                            misc.getnick(xmpp, from_jid))
                    raise SystemExit
                else:
                    misc.quiting = False
                    msg.reply(_('Error: Permission denied.')).send()
            else:
                msg.reply(_('Error: Permission denied.')).send()
            return

        if cmd[0] == 'kick':
            if from_jid in config.admins:
                if len(cmd) <= 1:
                    msg.reply(
                        misc.replace_prefix(
                            _('Error: /-kick takes at least one argument.'),
                            prefix)).send()
                    return
                if len(cmd) > 2:
                    reason = msg['body'].split(None, 2)[2]
                else:
                    reason = None
                success = False
                for to_jid in misc.find_users(xmpp, cmd[1], True):
                    success = True
                    sys.stderr.write('Kicking %s.' % to_jid)
                    if reason:
                        xmpp.send_message(
                            mto=to_jid,
                            mbody=_('You have been kicked by %s. (%s)') %
                            (misc.getnick(xmpp, from_jid), reason),
                            mtype='chat')
                    else:
                        xmpp.send_message(
                            mto=to_jid,
                            mbody=_('You have been kicked by %s.') %
                            misc.getnick(xmpp, from_jid),
                            mtype='chat')
                    if to_jid in misc.data['stop']:
                        del misc.data['stop'][to_jid]
                    to_nick = misc.getnick(xmpp, to_jid)
                    misc.del_nicktable(xmpp, to_jid)
                    try:
                        xmpp.del_roster_item(to_jid)
                    except Exception:
                        pass
                    if reason:
                        xmpp.send_except(
                            to_jid,
                            _('%s has been kicked by %s. (%s)') %
                            (to_nick, misc.getnick(xmpp, from_jid), reason))
                    else:
                        xmpp.send_except(
                            to_jid,
                            _('%s has been kicked by %s.') %
                            (to_nick, misc.getnick(xmpp, from_jid)))
                    sys.stderr.write('\n')
                if success:
                    misc.save_data()
                else:
                    msg.reply(
                        _('Error: User %s is not a member of this group.') %
                        (cmd[1])).send()
            else:
                msg.reply(_('Error: Permission denied.')).send()
            return

        if cmd[0] == 'quiet':
            if from_jid in config.admins:
                if len(cmd) <= 1:
                    msg.reply(
                        misc.replace_prefix(
                            _('Error: /-quiet takes at least one argument.'),
                            prefix)).send()
                    return
                if len(cmd) > 2:
                    to_time = ''.join(cmd[2:])
                else:
                    to_time = None
                try:
                    if to_time in ('ever', 'forever', None):
                        to_time = None
                    elif to_time in ('off', 'never'):
                        to_time = 'off'
                    else:
                        to_time = misc.TimeUnit(to_time)
                        if to_time > 0:
                            to_time = time.time() + misc.TimeUnit(to_time)
                        else:
                            to_time = 'off'
                except ValueError:
                    msg.reply(_('Error: Invalid time specification.')).send()
                    return
                success = False
                for to_jid in misc.find_users(xmpp, cmd[1], True):
                    success = True
                    sys.stderr.write('Quieting %s.' % to_jid)
                    if to_jid in misc.data['quiet']:
                        orig_time = misc.data['quiet'][to_jid]
                    else:
                        orig_time = 'off'
                    if to_time != 'off':
                        misc.data['quiet'][to_jid] = to_time
                    else:
                        if to_jid in misc.data['quiet']:
                            del misc.data['quiet'][to_jid]
                            try:
                                if to_jid not in data[
                                        'stop'] and to_jid not in data['quiet']:
                                    xmpp.send_presence(
                                        pto=to_jid,
                                        pshow='',
                                        pnick=config.group_nick,
                                        pstatus=config.group_topic)
                            except Exception:
                                pass
                    if orig_time == to_time:
                        continue
                    if to_time is None:
                        xmpp.send_message(
                            mto=to_jid,
                            mbody=_('You have been quieted by %s.') %
                            misc.getnick(xmpp, from_jid),
                            mtype='chat')
                        xmpp.send_presence(pto=to_jid,
                                           pshow='dnd',
                                           pnick=config.group_nick,
                                           pstatus=config.group_topic)
                    elif to_time == 'off':
                        xmpp.send_message(
                            mto=to_jid,
                            mbody=_('You have been stopped quieting by %s.') %
                            misc.getnick(xmpp, from_jid),
                            mtype='chat')
                        xmpp.send_presence(pto=to_jid,
                                           pshow='',
                                           pnick=config.group_nick,
                                           pstatus=config.group_topic)
                    else:
                        xmpp.send_message(
                            mto=to_jid,
                            mbody=_('You have been quieted by %s until %s.') %
                            (misc.getnick(xmpp,
                                          from_jid), misc.lctime(to_time)),
                            mtype='chat')
                        xmpp.send_presence(pto=to_jid,
                                           pshow='dnd',
                                           pnick=config.group_nick,
                                           pstatus=config.group_topic)
                    to_nick = misc.getnick(xmpp, to_jid)
                    if to_time is None:
                        xmpp.send_except(
                            to_jid,
                            _('%s has been quieted by %s.') %
                            (to_nick, misc.getnick(xmpp, from_jid)))
                    elif to_time == 'off':
                        xmpp.send_except(
                            to_jid,
                            _('%s has been stopped quieting by %s.') %
                            (to_nick, misc.getnick(xmpp, from_jid)))
                    else:
                        xmpp.send_except(
                            to_jid,
                            _('%s has been quieted by %s until %s.') %
                            (to_nick, misc.getnick(
                                xmpp, from_jid), misc.lctime(to_time)))
                    sys.stderr.write('\n')
                if success:
                    misc.save_data()
                else:
                    msg.reply(
                        _('Error: User %s is not a member of this group.') %
                        (cmd[1])).send()
            else:
                msg.reply(_('Error: Permission denied.')).send()
            return

        if cmd[0] == 'block':
            if len(cmd) > 1:
                isAdmin = from_jid in config.admins
                needsave = False
                for i in cmd[1:]:
                    success = False
                    for to_jid in misc.find_users(xmpp, i, isAdmin):
                        success = True
                        sys.stderr.write('Blocking %s by %s.' %
                                         (to_jid, from_jid))
                        if from_jid not in misc.data['block']:
                            misc.data['block'][from_jid] = []
                        if to_jid not in misc.data['block'][from_jid]:
                            needsave = True
                            misc.data['block'][from_jid].append(to_jid)
                            xmpp.send_message(
                                mto=to_jid,
                                mbody=_('You have been blocked by %s.') %
                                misc.getnick(xmpp, from_jid),
                                mtype='chat')
                            xmpp.send_message(
                                mto=from_jid,
                                mbody=
                                _('You will not receive messages from %s anymore.'
                                  ) % misc.getnick(xmpp, to_jid),
                                mtype='chat')
                        sys.stderr.write('\n')
                    if not success:
                        msg.reply(
                            _('Error: User %s is not a member of this group.')
                            % (cmd[1])).send()
                if needsave:
                    misc.save_data()
            else:
                if from_jid in misc.data['block']:
                    msg.reply(
                        _('Your blocking list: %s') % ' '.join([
                            misc.getnick(xmpp, i)
                            for i in misc.data['block'][from_jid]
                        ])).send()
                else:
                    msg.reply(_('Your blocking list is empty.')).send()
            return

        if cmd[0] == 'unblock':
            if len(cmd) > 1:
                if from_jid not in misc.data['block']:
                    return
                isAdmin = from_jid in config.admins
                needsave = False
                for i in cmd[1:]:
                    success = False
                    for to_jid in misc.find_users(xmpp, i, isAdmin):
                        success = True
                        sys.stderr.write('Unblocking %s by %s.' %
                                         (to_jid, from_jid))
                        if to_jid in misc.data['block'][from_jid]:
                            needsave = True
                            misc.data['block'][from_jid].remove(to_jid)
                            xmpp.send_message(
                                mto=to_jid,
                                mbody=_('You have been unblocked by %s.') %
                                misc.getnick(xmpp, from_jid),
                                mtype='chat')
                            xmpp.send_message(
                                mto=from_jid,
                                mbody=
                                _('You will receive messages from %s from now on.'
                                  ) % misc.getnick(xmpp, to_jid),
                                mtype='chat')
                        sys.stderr.write('\n')
                    if not success:
                        msg.reply(
                            _('Error: User %s is not a member of this group.')
                            % (cmd[1])).send()
                if needsave:
                    if not misc.data['block'][from_jid]:
                        del misc.data['block'][from_jid]
                    misc.save_data()
            else:
                msg.reply(
                    misc.replace_prefix(
                        _('Error: /-unblock takes at least one argument.'),
                        prefix)).send()
            return

        if cmd[0] == 'setnick':
            if len(cmd) == 3:
                if from_jid in config.admins:
                    to_jid = misc.getjid(xmpp, cmd[1])
                    if to_jid:
                        new_nick = cmd[2]
                        if not misc.isnickvalid(new_nick):
                            msg.reply(_('Nickname %s not vaild.') %
                                      new_nick).send()
                        elif misc.getnick(xmpp, new_nick):
                            msg.reply(
                                _('Nickname %s is already in use.') %
                                new_nick).send()
                        else:
                            old_nick = misc.getnick(xmpp, cmd[1])
                            misc.change_nicktable(xmpp, to_jid, new_nick)
                            xmpp.update_roster(to_jid, name=new_nick)
                            xmpp.send_except(
                                None,
                                _('%s is forced to changed its nick to %s.') %
                                (old_nick, new_nick))
                    else:
                        msg.reply(
                            _('Error: User %s is not a member of this group.')
                            % (cmd[1])).send()
                    return
                elif misc.getjid(xmpp, cmd[1]) == from_jid:
                    cmd[0] = 'nick'
                    del cmd[1]
                else:
                    msg.reply(_('Error: Permission denied.')).send()
                    return
            else:
                msg.reply(
                    misc.replace_prefix(
                        _('Error: /-setnick takes exactly two arguments.'),
                        prefix)).send()
                return

        if cmd[0] == 'nick':
            if len(cmd) == 1:
                msg.reply(
                    _('Your current nickname is %s.') %
                    misc.getnick(xmpp, from_jid)).send()
            elif len(cmd) >= 2:
                new_nick = cmd[1]
                for i in cmd[2:]:
                    new_nick += i.capitalize()
                if not misc.isnickvalid(new_nick):
                    msg.reply(_('Nickname %s not vaild.') % new_nick).send()
                elif misc.getnick(xmpp, new_nick):
                    msg.reply(_('Nickname %s is already in use.') %
                              new_nick).send()
                else:
                    oldnick = misc.getnick(xmpp, from_jid)
                    misc.change_nicktable(xmpp, from_jid, new_nick)
                    xmpp.update_roster(from_jid, name=new_nick)
                    xmpp.send_except(
                        None,
                        _('%s changed its nick to %s.') % (oldnick, new_nick))
            else:
                msg.reply(
                    misc.replace_prefix(
                        _('Error: /-nick takes exactly one argument.'),
                        prefix)).send()
            return

        if cmd[0] == 'ls':
            isAdmin = from_jid in config.admins
            option_a = False
            option_l = False
            glob = []
            for i in cmd[1:]:
                if i.startswith('-'):
                    if 'a' in i:
                        option_a = True
                    if 'l' in i:
                        option_l = True
                else:
                    glob.append(i)
            s = ''
            user_count = 0
            for i in misc.find_users(xmpp, glob, isAdmin):
                to_resources = xmpp.client_roster[i].resources
                if option_a or to_resources:
                    user_count += 1
                    s += '\n\t%s' % misc.getnick(xmpp, i)
                    if option_l:
                        if not misc.check_time(xmpp, misc.data['stop'], i):
                            s += '\t' + _('<Stopped>')
                        if to_resources:
                            to_priority = -1
                            to_show = ''
                            to_status = 'unavailable'
                            for j in to_resources:
                                if to_resources[j][
                                        'priority'] > to_priority or (
                                            to_resources[j]['priority']
                                            == to_priority
                                            and misc.compare_status(
                                                to_resources[j]['show'],
                                                to_status) >= 0):
                                    to_priority = to_resources[j]['priority']
                                    to_show = to_resources[j]['show']
                                    to_status = to_resources[j]['status']
                            s += '\t(%s)' % misc.get_status_name(to_show)
                            if to_status:
                                s += ' [%s]' % ' '.join(to_status.splitlines())
                        else:
                            s += '\t(%s)' % _('unavailable')
                    else:
                        if isAdmin:
                            s += '\t(%s)' % i
            s += '\n' + (_('Total %d') % user_count)
            msg.reply(s).send()
            return

        if cmd[0] == 'whois':
            isAdmin = from_jid in config.admins
            glob = []
            for i in cmd[1:]:
                if not i.startswith('-'):
                    glob.append(i)
            if not glob:
                msg.reply(
                    misc.replace_prefix(
                        _('Error: /-whois takes at least one argument.'),
                        prefix)).send()
                return
            s = ''
            success = False
            for i in misc.find_users(xmpp, glob, isAdmin):
                success = True
                s += '\n\n' + _('Nickname:\t%s') % misc.getnick(xmpp, i)
                if isAdmin:
                    s += '\n' + _('Jabber ID:\t%s') % i
                else:
                    s += '\n' + _('Jabber ID:\t%s@%s') % ('*' * len(
                        sleekxmpp.JID(i).user), sleekxmpp.JID(i).domain)
                if not misc.check_time(xmpp, misc.data['stop'], i):
                    if misc.data['stop'][i] is None:
                        s += '\n' + _('Not receiving messages.')
                    else:
                        s += '\n' + _('Not receiving messages until %s.'
                                      ) % misc.lctime(misc.data['stop'][i])
                if i in misc.data['block']:
                    s += '\n' + _('Blocking:\t%s') % ' '.join(
                        [misc.getnick(xmpp, j) for j in misc.data['block'][i]])
                if not misc.check_time(xmpp, misc.data['quiet'], i):
                    if misc.data['quiet'][i] is None:
                        s += '\n' + _('Quieted.')
                    else:
                        s += '\n' + _('Quieted until %s.') % misc.lctime(
                            misc.data['quiet'][i])
                blockby = []
                for j in misc.data['block']:
                    if i in misc.data['block'][j]:
                        blockby.append(j)
                if blockby:
                    s += '\n' + _('Blocked by:\t%s') % ' '.join(
                        [misc.getnick(xmpp, j) for j in blockby])
                to_resources = xmpp.client_roster[i].resources
                if to_resources:
                    s += '\n' + _('Online resources:')
                    for j in to_resources:
                        s += '\n\t%s\t(%s)' % (
                            j, misc.get_status_name(to_resources[j]['show']))
                        if to_resources[j]['status']:
                            s += '\t[%s]' % ' '.join(
                                to_resources[j]['status'].splitlines())
            if not success:
                s = '\n' + _(
                    'Error: User %s is not a member of this group.') % (cmd[1])
            msg.reply(s[1:8192]).send()
            return

        msg.reply(
            misc.replace_prefix(
                _('Error: Unknown command. For help, type /-help'),
                prefix)).send()
    except SystemExit:
        raise
    except Exception as e:
        try:
            msg.reply(
                _('An error occured: %s: %s') %
                (e.__class__.__name__, e)).send()
        except Exception:
            pass