Esempio n. 1
0
    def pager_trigger(self, mess, args):
        """ Trigger an incident """
        if self.config:
            if mess.getType() == "chat":
                return "Sorry, you need to use group chat for PagerDuty commands"
            else:
                pd_api = "https://events.pagerduty.com/generic/2010-04-15/create_event.json"
                body = {
                    'service_key': self.config['SERVICE_API_KEY'],
                    'event_type': 'trigger',
                    'description': 'Urgent page via chat',
                    'details': {
                        'requestor': get_sender_username(mess),
                        'message': " ".join(args)
                    }
                }

                response = requests.post(pd_api, data=json.dumps(body))
                if response.status_code in (200, ):
                    return "Triggered incident %s" % (
                        response.json()['incident_key'], )
                else:
                    logging.error("[PagerDuty] Non-200 response: %s" %
                                  response.status_code)
                    logging.error("[PagerDuty] Body: %s" % response.json())
                    return "Sorry, something went wrong. You should check the logs."
        else:
            return "Sorry, PagerDuty is not configured"
Esempio n. 2
0
File: base.py Progetto: qznc/err
    def _process_command(self, mess, cmd, args, match):
        """Process and execute a bot command"""
        logging.info("Processing command {} with parameters '{}'".format(cmd, args))

        jid = mess.frm
        username = get_sender_username(mess)
        user_cmd_history = self.cmd_history[username]

        if (cmd, args) in user_cmd_history:
            user_cmd_history.remove((cmd, args))  # Avoids duplicate history items

        try:
            self.check_command_access(mess, cmd)
        except ACLViolation as e:
            if not HIDE_RESTRICTED_ACCESS:
                self.send_simple_reply(mess, str(e))
            return

        f = self.re_commands[cmd] if match else self.commands[cmd]

        if f._err_command_admin_only and BOT_ASYNC:
            # If it is an admin command, wait until the queue is completely depleted so
            # we don't have strange concurrency issues on load/unload/updates etc...
            self.thread_pool.wait()

        if f._err_command_historize:
            user_cmd_history.append((cmd, args))  # add it to the history only if it is authorized to be so

        # Don't check for None here as None can be a valid argument to str.split.
        # '' was chosen as default argument because this isn't a valid argument to str.split()
        if not match and f._err_command_split_args_with != '':
            try:
                if hasattr(f._err_command_split_args_with, "parse_args"):
                    args = f._err_command_split_args_with.parse_args(args)
                elif callable(f._err_command_split_args_with):
                    args = f._err_command_split_args_with(args)
                else:
                    args = args.split(f._err_command_split_args_with)
            except Exception as e:
                self.send_simple_reply(
                    mess,
                    "Sorry, I couldn't parse your arguments. {}".format(e)
                )
                return

        if BOT_ASYNC:
            wr = WorkRequest(
                self._execute_and_send,
                [],
                {'cmd': cmd, 'args': args, 'match': match, 'mess': mess, 'jid': jid,
                 'template_name': f._err_command_template}
            )
            self.thread_pool.putRequest(wr)
            if f._err_command_admin_only:
                # Again, if it is an admin command, wait until the queue is completely
                # depleted so we don't have strange concurrency issues.
                self.thread_pool.wait()
        else:
            self._execute_and_send(cmd=cmd, args=args, match=match, mess=mess, jid=jid,
                                   template_name=f._err_command_template)
Esempio n. 3
0
    def xup_remove(self, mess, args):
        """Remove yourself from the ready list"""
        user = get_sender_username(mess)

        del self['users'][user]

        return "Done."
Esempio n. 4
0
    def xup_remove(self, mess, args):
        """Remove yourself from the ready list"""
        user = get_sender_username(mess)

        del self['users'][user]

        return "Done."
Esempio n. 5
0
    def pager_register(self, mess, args):
        """ Register as a PagerDuty user with the bot via your email address """
        if self.config:
            if mess.getType() == "chat":
                return "Sorry, you need to use group chat for PagerDuty commands"
            else:
                if len(args) <= 0:
                    return "I can't register you without an email address"
                else:
                    users = self.get_users()
                    uid = get_sender_username(mess)
                    email = args[0]

                    try:
                        user_index = map(itemgetter('uid'), users).index(uid)
                        user = users[user_index]
                        return "You are already registered as %s" % (user['email'],)
                    except:
                        try:
                            existing_user_index = map(itemgetter('email'), users).index(email)
                            existing_user = users[existing_user_index]
                            return "The email address you provided is already registered to %s" % (existing_user['uid'],)
                        except:
                            pd_id = self.get_pd_id_by_email(email)

                            if pd_id is None:
                                return "Sorry, I couldn't find a PagerDuty user with that email address"
                            else:
                                logging.info("[PagerDuty] registering user ID %s as %s" % (uid, email,))
                                self.add_user(uid=uid, email=email, pd_id=pd_id)
                                updated_user_list = self.get_users()
                                logging.debug("[PagerDuty] new user list: %s" % (updated_user_list,))
                                return "You are now licensed to kill"
        else:
            return "Sorry, PagerDuty is not configured"
Esempio n. 6
0
 def pager_resolve(self, mess, args):
     """ Resolve an incident by it's alphanumeric ID """
     if self.config:
         if mess.getType() == "chat":
             return "Sorry, you need to use group chat for PagerDuty commands"
         else:
             try:
                 requestor = self.get_user(get_sender_username(mess))
             except:
                 return "Sorry, I don't know who you are. Please use !pager register to teach me your email address."
             try:
                 incident_id = args[0]
                 logging.info(
                     "[PagerDuty] resolving incident %s by request of %s" %
                     (incident_id, requestor['uid']))
                 self.pager.incidents.update(requestor['pd_id'], {
                     'id': incident_id,
                     'status': 'resolved'
                 })
                 return "Resolved incident %s" % (incident_id, )
             except HTTPError as e:
                 logging.error(
                     "[PagerDuty] Error resolving incident %s: %s" % (
                         incident_id,
                         e,
                     ))
                 return "Failed to resolve incident %s: %s" % (
                     incident_id,
                     e,
                 )
     else:
         return "Sorry, PagerDuty is not configured"
Esempio n. 7
0
    def pager_steal(self, mess, args):
        """ Steal the pager for N minutes """
        if self.config:
            if mess.getType() == "chat":
                return "Sorry, you need to use group chat for PagerDuty commands"
            else:
                if len(args) <= 0:
                    return "Sorry, you need to specify the number of minutes for which you'd like to steal the pager"
                else:
                    requestor_name = get_sender_username(mess)
                    users = self.get_users()
                    requestor_index = map(itemgetter('uid'),
                                          users).index(requestor_name)
                    requestor = users[requestor_index]
                    schedule_id = self.config['SCHEDULE_ID']

                    logging.info("[PagerDuty] override requestor found: %s" %
                                 (requestor, ))

                    try:
                        override_duration = int(args[0])
                    except:
                        return "Sorry, I could not transform %s into an integer"

                    if requestor['pd_id'] == self.get_oncall_pd_id(
                            schedule_id):
                        return "Sorry, you are already on call"
                    else:
                        local_tz = get_localzone()
                        schedule_tz = pytz.timezone(
                            self.config['SCHEDULE_TIMEZONE'])
                        local_dt = local_tz.localize(datetime.now())
                        now = local_dt.astimezone(schedule_tz)
                        later = now + timedelta(minutes=override_duration)
                        try:
                            schedule = self.pager.schedules.show(schedule_id)
                            schedule.overrides.create(
                                start=now.isoformat(),
                                end=later.isoformat(),
                                user_id=requestor['pd_id'])
                            return "Rejoice ye oncall, %s has the pager for %s minutes(s)" % (
                                requestor['uid'],
                                override_duration,
                            )
                        except HTTPError as e:
                            logging.error(
                                "[PagerDuty] Error overriding schedule %s: %s"
                                % (
                                    schedule_id,
                                    e,
                                ))
                            raise Exception(
                                "Error overriding schedule %s: %s" % (
                                    schedule_id,
                                    e,
                                ))
        else:
            return "Sorry, PagerDuty is not configured"
Esempio n. 8
0
 def history(self, mess, args):
     """display the command history"""
     answer = []
     user_cmd_history = self.cmd_history[get_sender_username(mess)]
     l = len(user_cmd_history)
     for i in range(0, l):
         c = user_cmd_history[i]
         answer.append("%2i:%s%s %s" % (l - i, self.prefix, c[0], c[1]))
     return "\n".join(answer)
Esempio n. 9
0
    def callback_message(self, conn, mess):
        """Listen for Die Hard mentions and interject random lines from those
        characters who were mentioned.
        """
        logging.debug("mess.getFrom().getStripped(): " + mess.getFrom().getStripped())
        logging.debug("config.BOT_IDENTITY['username']: "******"username"])
        logging.debug("get_sender_username(mess): " + get_sender_username(mess))
        logging.debug("config.CHATROOM_FN: " + config.CHATROOM_FN)
        if (mess.getFrom().getStripped() == config.BOT_IDENTITY["username"]) or (get_sender_username(mess) == config.CHATROOM_FN):
            logging.debug("Ignore a message from myself")
            return False

        message = ""
        for character in DieHard.CHARACTERS:
            if mess.getBody().find("(%s)" % character) != -1:
                message += "(%s) %s  " % (character, self.diehard.get_random(character))
        if message:
            self.send(mess.getFrom(), message, message_type=mess.getType())
Esempio n. 10
0
 def history(self, mess, args):
     """display the command history"""
     answer = []
     user_cmd_history = self.cmd_history[get_sender_username(mess)]
     l = len(user_cmd_history)
     for i in range(0, l):
         c = user_cmd_history[i]
         answer.append('%2i:%s%s %s' % (l - i, self.prefix, c[0], c[1]))
     return '\n'.join(answer)
Esempio n. 11
0
    def xup(self, mess, args):
        """Add yourself to the ready list, you can include an optional message."""

        user = get_sender_username(mess)
        xup_args = {'user': user, 'args': args, 'message': mess.getBody(), 'time': datetime.utcnow()}

        self['users'][user] = xup_args

        return "Done."
Esempio n. 12
0
    def xup(self, mess, args):
        """Add yourself to the ready list, you can include an optional message."""

        user = get_sender_username(mess)
        xup_args = {
            'user': user,
            'args': args,
            'message': mess.getBody(),
            'time': datetime.utcnow()
        }

        self['users'][user] = xup_args

        return "Done."
Esempio n. 13
0
    def callback_message(self, conn, mess):
        """Listen for Die Hard mentions and interject random lines from those
        characters who were mentioned.
        """
        logging.debug("mess.getFrom().getStripped(): " +
                      mess.getFrom().getStripped())
        logging.debug("config.BOT_IDENTITY['username']: "******"username"])
        logging.debug("get_sender_username(mess): " +
                      get_sender_username(mess))
        logging.debug("config.CHATROOM_FN: " + config.CHATROOM_FN)
        if (mess.getFrom().getStripped() == config.BOT_IDENTITY["username"]
            ) or (get_sender_username(mess) == config.CHATROOM_FN):
            logging.debug("Ignore a message from myself")
            return False

        message = ""
        for character in DieHard.CHARACTERS:
            if mess.getBody().find("(%s)" % character) != -1:
                message += "(%s) %s  " % (character,
                                          self.diehard.get_random(character))
        if message:
            self.send(mess.getFrom(), message, message_type=mess.getType())
Esempio n. 14
0
 def pager_whoami(self, mess, args):
     """ ... and how did I get here?"""
     if self.config:
         if mess.getType() == "chat":
             return "Sorry, you need to use group chat for PagerDuty commands"
         else:
             uid = get_sender_username(mess)
             users = self.get_users()
             try:
                 user_index = map(itemgetter('uid'), users).index(uid)
                 user = users[user_index]
                 return "I have you registered as %s with PagerDuty ID %s" % (user['email'], user['pd_id'],)
             except ValueError as e:
                 return "I don't think I know you: %s" % (e,)
     else:
         return "Sorry, PagerDuty is not configured"
Esempio n. 15
0
	def callback_message(self, conn, mess):
		command = re.match('s/([^/]+)/([^/]*)/?', mess.getBody())
		if command:
			for old_mess in self.backlog[conn]:
				try:
					(replaced, n) = re.subn(command.group(1), command.group(2), old_mess.getBody())
				except Exception as e:
					self.send(mess.getFrom(), "regex does not compute", message_type=mess.getType())
					return

				if n > 0:
					reply = '{0} meant: "{1}"'.format(get_sender_username(old_mess), replaced)
					self.send(mess.getFrom(), reply, message_type=mess.getType())
					return

		self.backlog[conn] = ([mess] + self.backlog[conn])[:self.config['BACKLOG_LENGTH']]
Esempio n. 16
0
    def pager_register(self, mess, args):
        """ Register as a PagerDuty user with the bot via your email address """
        if self.config:
            if mess.getType() == "chat":
                return "Sorry, you need to use group chat for PagerDuty commands"
            else:
                if len(args) <= 0:
                    return "I can't register you without an email address"
                else:
                    users = self.get_users()
                    uid = get_sender_username(mess)
                    email = args[0]

                    try:
                        user_index = map(itemgetter('uid'), users).index(uid)
                        user = users[user_index]
                        return "You are already registered as %s" % (
                            user['email'], )
                    except:
                        try:
                            existing_user_index = map(itemgetter('email'),
                                                      users).index(email)
                            existing_user = users[existing_user_index]
                            return "The email address you provided is already registered to %s" % (
                                existing_user['uid'], )
                        except:
                            pd_id = self.get_pd_id_by_email(email)

                            if pd_id is None:
                                return "Sorry, I couldn't find a PagerDuty user with that email address"
                            else:
                                logging.info(
                                    "[PagerDuty] registering user ID %s as %s"
                                    % (
                                        uid,
                                        email,
                                    ))
                                self.add_user(uid=uid,
                                              email=email,
                                              pd_id=pd_id)
                                updated_user_list = self.get_users()
                                logging.debug("[PagerDuty] new user list: %s" %
                                              (updated_user_list, ))
                                return "You are now licensed to kill"
        else:
            return "Sorry, PagerDuty is not configured"
Esempio n. 17
0
	def ping(self, mess, args):
		"""A command which simply returns 'Example'"""
		who=args.split(' ',1)
		if len(who) > 1:
			pingTarget=who[0]+"@ping.pfralliance.com"
			sender=get_sender_username(mess)
			time=datetime.utcnow().strftime('%H:%M:%S')
			content=who[1]+"\n\n This is a broadcast sent at "+time+" EVE Time to "+who[0]+" from "+sender+".  Replies are not monitored."
			self.send(
    			pingTarget,
			content,
    			message_type="chat"
			)
			output="Ping sent to "+who[0]
			return output
		else:
			return "You did it wrong! Try !ping usergroup message.  Check !groups for a list of groups you can ping."
Esempio n. 18
0
 def pager_unregister(self, mess, args):
     """ Remove your PagerDuty user registration """
     if self.config:
         if mess.getType() == "chat":
             return "Sorry, you need to use group chat for PagerDuty commands"
         else:
             users = self.get_users()
             uid = get_sender_username(mess)
             for user in users:
                 if user['uid'] == uid:
                     logging.info("[PagerDuty] unregistering user ID %s" % (uid,))
                     self.remove_user(uid=uid)
                     updated_user_list = self.get_users()
                     logging.debug("[PagerDuty] new user list: %s" % (updated_user_list,))
                     return "You're dead to me"
             else:
                 return "Sorry, I'm afraid I don't know who you are to begin with"
     else:
             return "Sorry, PagerDuty is not configured"
Esempio n. 19
0
 def pager_whoami(self, mess, args):
     """ ... and how did I get here?"""
     if self.config:
         if mess.getType() == "chat":
             return "Sorry, you need to use group chat for PagerDuty commands"
         else:
             uid = get_sender_username(mess)
             users = self.get_users()
             try:
                 user_index = map(itemgetter('uid'), users).index(uid)
                 user = users[user_index]
                 return "I have you registered as %s with PagerDuty ID %s" % (
                     user['email'],
                     user['pd_id'],
                 )
             except ValueError as e:
                 return "I don't think I know you: %s" % (e, )
     else:
         return "Sorry, PagerDuty is not configured"
Esempio n. 20
0
 def pager_resolve(self, mess, args):
     """ Resolve an incident by it's alphanumeric ID """
     if self.config:
         if mess.getType() == "chat":
             return "Sorry, you need to use group chat for PagerDuty commands"
         else:
             try:
                 requestor = self.get_user(get_sender_username(mess))
             except:
                 return "Sorry, I don't know who you are. Please use !pager register to teach me your email address."
             try:
                 incident_id = args[0]
                 logging.info("[PagerDuty] resolving incident %s by request of %s" % (incident_id, requestor['uid']))
                 self.pager.incidents.update(requestor['pd_id'], {'id': incident_id, 'status': 'resolved'})
                 return "Resolved incident %s" % (incident_id,)
             except HTTPError as e:
                 logging.error("[PagerDuty] Error resolving incident %s: %s" % (incident_id, e,))
                 return "Failed to resolve incident %s: %s" % (incident_id, e,)
     else:
         return "Sorry, PagerDuty is not configured"
Esempio n. 21
0
 def pager_unregister(self, mess, args):
     """ Remove your PagerDuty user registration """
     if self.config:
         if mess.getType() == "chat":
             return "Sorry, you need to use group chat for PagerDuty commands"
         else:
             users = self.get_users()
             uid = get_sender_username(mess)
             for user in users:
                 if user['uid'] == uid:
                     logging.info("[PagerDuty] unregistering user ID %s" %
                                  (uid, ))
                     self.remove_user(uid=uid)
                     updated_user_list = self.get_users()
                     logging.debug("[PagerDuty] new user list: %s" %
                                   (updated_user_list, ))
                     return "You're dead to me"
             else:
                 return "Sorry, I'm afraid I don't know who you are to begin with"
     else:
         return "Sorry, PagerDuty is not configured"
Esempio n. 22
0
    def pager_steal(self, mess, args):
        """ Steal the pager for N minutes """
        if self.config:
            if mess.getType() == "chat":
                return "Sorry, you need to use group chat for PagerDuty commands"
            else:
                if len(args) <= 0:
                    return "Sorry, you need to specify the number of minutes for which you'd like to steal the pager"
                else:
                    requestor_name = get_sender_username(mess)
                    users = self.get_users()
                    requestor_index = map(itemgetter('uid'), users).index(requestor_name)
                    requestor = users[requestor_index]
                    schedule_id = self.config['SCHEDULE_ID']

                    logging.info("[PagerDuty] override requestor found: %s" % (requestor,))

                    try:
                        override_duration = int(args[0])
                    except:
                        return "Sorry, I could not transform %s into an integer"

                    if requestor['pd_id'] == self.get_oncall_pd_id(schedule_id):
                        return "Sorry, you are already on call"
                    else:
                        local_tz = get_localzone()
                        schedule_tz = pytz.timezone(self.config['SCHEDULE_TIMEZONE'])
                        local_dt = local_tz.localize(datetime.now())
                        now = local_dt.astimezone(schedule_tz)
                        later = now + timedelta(minutes=override_duration)
                        try:
                            schedule = self.pager.schedules.show(schedule_id)
                            schedule.overrides.create(start=now.isoformat(), end=later.isoformat(), user_id=requestor['pd_id'])
                            return "Rejoice ye oncall, %s has the pager for %s minutes(s)" % (requestor['uid'], override_duration,)
                        except HTTPError as e:
                            logging.error("[PagerDuty] Error overriding schedule %s: %s" % (schedule_id, e,))
                            raise Exception("Error overriding schedule %s: %s" % (schedule_id, e,))
        else:
            return "Sorry, PagerDuty is not configured"
Esempio n. 23
0
    def pager_trigger(self, mess, args):
        """ Trigger an incident """
        if self.config:
            if mess.getType() == "chat":
                return "Sorry, you need to use group chat for PagerDuty commands"
            else:
                pd_api = "https://events.pagerduty.com/generic/2010-04-15/create_event.json"
                body = {'service_key': self.config['SERVICE_API_KEY'],
                        'event_type': 'trigger',
                        'description': 'Urgent page via chat',
                        'details': {'requestor': get_sender_username(mess),
                                    'message': " ".join(args)}
                        }

                response = requests.post(pd_api, data=json.dumps(body))
                if response.status_code in (200,):
                    return "Triggered incident %s" % (response.json()['incident_key'],)
                else:
                    logging.error("[PagerDuty] Non-200 response: %s" % response.status_code)
                    logging.error("[PagerDuty] Body: %s" % response.json())
                    return "Sorry, something went wrong. You should check the logs."
        else:
            return "Sorry, PagerDuty is not configured"
Esempio n. 24
0
    def callback_message(self, conn, mess):
        command = re.match('s/([^/]+)/([^/]*)/?', mess.getBody())
        if command:
            for old_mess in self.backlog:
                try:
                    (replaced, n) = re.subn(command.group(1), command.group(2),
                                            old_mess.getBody())
                except Exception as e:
                    self.send(mess.getFrom(),
                              "regex does not compute",
                              message_type=mess.getType())
                    return

                if n > 0:
                    reply = '{0} meant: "{1}"'.format(
                        get_sender_username(old_mess), replaced)
                    self.send(mess.getFrom(),
                              reply,
                              message_type=mess.getType())
                    return

        self.backlog.insert(0, mess)
        self.backlog = self.backlog[:self.config['BACKLOG_LENGTH']]
Esempio n. 25
0
    def callback_message(self, conn, mess):
        """
        Needs to return False if we want to stop further treatment
        """
        # Prepare to handle either private chats or group chats
        type = mess.getType()
        jid = mess.getFrom()
        text = mess.getBody()
        username = get_sender_username(mess)
        user_cmd_history = self.cmd_history[username]

        if mess.isDelayed():
            logging.debug("Message from history, ignore it")
            return False

        if type not in ("groupchat", "chat"):
            logging.debug("unhandled message type %s" % mess)
            return False

        # Ignore messages from ourselves. Because it isn't always possible to get the
        # real JID from a MUC participant (including ourself), matching the JID against
        # ourselves isn't enough (see https://github.com/gbin/err/issues/90 for
        # background discussion on this). Matching against CHATROOM_FN isn't technically
        # correct in all cases because a MUC could give us another nickname, but it
        # covers 99% of the MUC cases, so it should suffice for the time being.
        if (jid.bareMatch(Identifier(self.jid))
                or type == "groupchat" and mess.getMuckNick() == CHATROOM_FN):
            logging.debug("Ignoring message from self")
            return False

        logging.debug("*** jid = %s" % jid)
        logging.debug("*** username = %s" % username)
        logging.debug("*** type = %s" % type)
        logging.debug("*** text = %s" % text)

        # If a message format is not supported (eg. encrypted),
        # txt will be None
        if not text:
            return False

        surpress_cmd_not_found = False

        prefixed = False  # Keeps track whether text was prefixed with a bot prefix
        only_check_re_command = False  # Becomes true if text is determed to not be a regular command
        tomatch = text.lower() if BOT_ALT_PREFIX_CASEINSENSITIVE else text
        if len(BOT_ALT_PREFIXES) > 0 and tomatch.startswith(
                self.bot_alt_prefixes):
            # Yay! We were called by one of our alternate prefixes. Now we just have to find out
            # which one... (And find the longest matching, in case you have 'err' and 'errbot' and
            # someone uses 'errbot', which also matches 'err' but would leave 'bot' to be taken as
            # part of the called command in that case)
            prefixed = True
            longest = 0
            for prefix in self.bot_alt_prefixes:
                l = len(prefix)
                if tomatch.startswith(prefix) and l > longest:
                    longest = l
            logging.debug("Called with alternate prefix '{}'".format(
                text[:longest]))
            text = text[longest:]

            # Now also remove the separator from the text
            for sep in BOT_ALT_PREFIX_SEPARATORS:
                # While unlikely, one may have separators consisting of
                # more than one character
                l = len(sep)
                if text[:l] == sep:
                    text = text[l:]
        elif type == "chat" and BOT_PREFIX_OPTIONAL_ON_CHAT:
            logging.debug(
                "Assuming '%s' to be a command because BOT_PREFIX_OPTIONAL_ON_CHAT is True"
                % text)
            # In order to keep noise down we surpress messages about the command
            # not being found, because it's possible a plugin will trigger on what
            # was said with trigger_message.
            surpress_cmd_not_found = True
        elif not text.startswith(BOT_PREFIX):
            only_check_re_command = True
        if text.startswith(BOT_PREFIX):
            text = text[len(BOT_PREFIX):]
            prefixed = True

        text = text.strip()
        text_split = text.split(' ')
        cmd = None
        command = None
        args = ''
        if not only_check_re_command:
            if len(text_split) > 1:
                command = (text_split[0] + '_' + text_split[1]).lower()
                if command in self.commands:
                    cmd = command
                    args = ' '.join(text_split[2:])

            if not cmd:
                command = text_split[0].lower()
                args = ' '.join(text_split[1:])
                if command in self.commands:
                    cmd = command
                    if len(text_split) > 1:
                        args = ' '.join(text_split[1:])

            if command == BOT_PREFIX:  # we did "!!" so recall the last command
                if len(user_cmd_history):
                    cmd, args = user_cmd_history[-1]
                else:
                    return False  # no command in history
            elif command.isdigit(
            ):  # we did "!#" so we recall the specified command
                index = int(command)
                if len(user_cmd_history) >= index:
                    cmd, args = user_cmd_history[-index]
                else:
                    return False  # no command in history

        # Try to match one of the regex commands if the regular commands produced no match
        matched_on_re_command = False
        if not cmd:
            if prefixed:
                commands = self.re_commands
            else:
                commands = {
                    k: self.re_commands[k]
                    for k in self.re_commands
                    if not self.re_commands[k]._err_command_prefix_required
                }

            for name, func in commands.items():
                match = func._err_command_re_pattern.search(text)
                if match:
                    logging.debug(
                        "Matching '{}' against '{}' produced a match".format(
                            text, func._err_command_re_pattern.pattern))
                    matched_on_re_command = True
                    self._process_command(mess, name, text, match)
                else:
                    logging.debug(
                        "Matching '{}' against '{}' produced no match".format(
                            text, func._err_command_re_pattern.pattern))
        if matched_on_re_command:
            return True

        if cmd:
            self._process_command(mess, cmd, args, match=None)
        elif not only_check_re_command:
            logging.debug("Command not found")
            if surpress_cmd_not_found:
                logging.debug("Surpressing command not found feedback")
            else:
                reply = self.unknown_command(mess, command, args)
                if reply is None:
                    reply = self.MSG_UNKNOWN_COMMAND % {'command': command}
                if reply:
                    self.send_simple_reply(mess, reply)
        return True
Esempio n. 26
0
    def callback_message(self, conn, mess):
        """
        Needs to return False if we want to stop further treatment
        """
        # Prepare to handle either private chats or group chats
        type = mess.getType()
        jid = mess.getFrom()
        text = mess.getBody()
        username = get_sender_username(mess)
        user_cmd_history = self.cmd_history[username]

        if mess.isDelayed():
            logging.debug("Message from history, ignore it")
            return False

        if type not in ("groupchat", "chat"):
            logging.debug("unhandled message type %s" % mess)
            return False

        logging.debug("*** jid = %s" % jid)
        logging.debug("*** username = %s" % username)
        logging.debug("*** type = %s" % type)
        logging.debug("*** text = %s" % text)

        # If a message format is not supported (eg. encrypted),
        # txt will be None
        if not text:
            return False

        surpress_cmd_not_found = False

        tomatch = text.lower() if BOT_ALT_PREFIX_CASEINSENSITIVE else text
        if len(BOT_ALT_PREFIXES) > 0 and tomatch.startswith(
                self.bot_alt_prefixes):
            # Yay! We were called by one of our alternate prefixes. Now we just have to find out
            # which one... (And find the longest matching, in case you have 'err' and 'errbot' and
            # someone uses 'errbot', which also matches 'err' but would leave 'bot' to be taken as
            # part of the called command in that case)
            longest = 0
            for prefix in self.bot_alt_prefixes:
                l = len(prefix)
                if tomatch.startswith(prefix) and l > longest:
                    longest = l
            text = text[longest:]

            # Now also remove the separator from the text
            for sep in BOT_ALT_PREFIX_SEPARATORS:
                # While unlikely, one may have separators consisting of
                # more than one character
                l = len(sep)
                if text[:l] == sep:
                    text = text[l:]
        elif type == "chat" and BOT_PREFIX_OPTIONAL_ON_CHAT:
            logging.debug(
                "Assuming '%s' to be a command because BOT_PREFIX_OPTIONAL_ON_CHAT is True"
                % text)
            # In order to keep noise down we surpress messages about the command
            # not being found, because it's possible a plugin will trigger on what
            # was said with trigger_message.
            surpress_cmd_not_found = True
        elif not text.startswith(BOT_PREFIX):
            return True
        if text.startswith(BOT_PREFIX):
            text = text[len(BOT_PREFIX):]

        text_split = text.strip().split(' ')
        cmd = None
        command = None
        args = ''
        if len(text_split) > 1:
            command = (text_split[0] + '_' + text_split[1]).lower()
            if command in self.commands:
                cmd = command
                args = ' '.join(text_split[2:])

        if not cmd:
            command = text_split[0].lower()
            args = ' '.join(text_split[1:])
            if command in self.commands:
                cmd = command
                if len(text_split) > 1:
                    args = ' '.join(text_split[1:])

        if command == BOT_PREFIX:  # we did "!!" so recall the last command
            if len(user_cmd_history):
                cmd, args = user_cmd_history[-1]
            else:
                return False  # no command in history
        elif command.isdigit(
        ):  # we did "!#" so we recall the specified command
            index = int(command)
            if len(user_cmd_history) >= index:
                cmd, args = user_cmd_history[-index]
            else:
                return False  # no command in history

        if (cmd, args) in user_cmd_history:
            user_cmd_history.remove((cmd, args))  # we readd it below

        if cmd:
            logging.info(
                "received command = %s matching [%s] with parameters [%s]" %
                (command, cmd, args))

            access, accessError = self.check_command_access(mess, cmd)
            if not access:
                if not HIDE_RESTRICTED_ACCESS:
                    self.send_simple_reply(mess, accessError)
                return False

            f = self.commands[cmd]

            if f._err_command_admin_only and BOT_ASYNC:
                self.thread_pool.wait(
                )  # If it is an admin command, wait that the queue is completely depleted so we don't have strange concurrency issues on load/unload/updates etc ...

            if f._err_command_historize:
                user_cmd_history.append(
                    (cmd, args)
                )  # add it to the history only if it is authorized to be so

            # Don't check for None here as None can be a valid argument to split.
            # '' was chosen as default argument because this isn't a valid argument to split()
            if f._err_command_split_args_with != '':
                args = args.split(f._err_command_split_args_with)
            if BOT_ASYNC:
                wr = WorkRequest(
                    self._execute_and_send, [], {
                        'cmd': cmd,
                        'args': args,
                        'mess': mess,
                        'jid': jid,
                        'template_name': f._err_command_template
                    })
                self.thread_pool.putRequest(wr)
                if f._err_command_admin_only:
                    self.thread_pool.wait(
                    )  # Again wait for the completion before accepting a new command that could generate weird concurrency issues
            else:
                self._execute_and_send(cmd=cmd,
                                       args=args,
                                       mess=mess,
                                       jid=jid,
                                       template_name=f._err_command_template)

        else:
            logging.debug("Command not found")
            if surpress_cmd_not_found:
                logging.debug("Surpressing command not found feedback")
            else:
                reply = self.unknown_command(mess, command, args)
                if reply is None:
                    reply = self.MSG_UNKNOWN_COMMAND % {'command': command}
                if reply:
                    self.send_simple_reply(mess, reply)

        return True
Esempio n. 27
0
 def helper(self, mess, args):
     output = func(self, mess, args)
     if len(output) > 8000:
         return "How appropriate, you code like a cow, {0}!".format(get_sender_username(mess))
     else:
         return output
Esempio n. 28
0
 def todo_create(self, mess, args):
   """Creates a new entry on the todo list. Syntax: !todo create <title>."""
   self.l.append(Entry(args, get_sender_username(mess)))
   self.write_csv_file()
   return "Created a new entry with id " + str(len(self.l)-1) + ", use !todo describe " + str(len(self.l)-1) + " to add a detailed description."
Esempio n. 29
0
    def callback_message(self, conn, mess):
        """
        Needs to return False if we want to stop further treatment
        """
        # Prepare to handle either private chats or group chats
        type = mess.getType()
        jid = mess.getFrom()
        text = mess.getBody()
        username = get_sender_username(mess)

        if mess.isDelayed():
            logging.debug("Message from history, ignore it")
            return False

        if type not in ("groupchat", "chat"):
            logging.debug("unhandled message type %s" % mess)
            return False

        logging.debug("*** jid = %s" % jid)
        logging.debug("*** username = %s" % username)
        logging.debug("*** type = %s" % type)
        logging.debug("*** text = %s" % text)

        # If a message format is not supported (eg. encrypted),
        # txt will be None
        if not text:
            return False

        surpress_cmd_not_found = False

        tomatch = text.lower() if BOT_ALT_PREFIX_CASEINSENSITIVE else text
        if len(BOT_ALT_PREFIXES) > 0 and tomatch.startswith(self.bot_alt_prefixes):
            # Yay! We were called by one of our alternate prefixes. Now we just have to find out
            # which one... (And find the longest matching, in case you have 'err' and 'errbot' and
            # someone uses 'errbot', which also matches 'err' but would leave 'bot' to be taken as
            # part of the called command in that case)
            longest = 0
            for prefix in self.bot_alt_prefixes:
                l = len(prefix)
                if tomatch.startswith(prefix) and l > longest:
                    longest = l
            text = text[longest:]

            # Now also remove the separator from the text
            for sep in BOT_ALT_PREFIX_SEPARATORS:
                # While unlikely, one may have separators consisting of
                # more than one character
                l = len(sep)
                if text[:l] == sep:
                    text = text[l:]
        elif type == "chat" and BOT_PREFIX_OPTIONAL_ON_CHAT:
            logging.debug("Assuming '%s' to be a command because BOT_PREFIX_OPTIONAL_ON_CHAT is True" % text)
            # In order to keep noise down we surpress messages about the command
            # not being found, because it's possible a plugin will trigger on what
            # was said with trigger_message.
            surpress_cmd_not_found = True
        elif not text.startswith(BOT_PREFIX):
            return True
        else:
            text = text[len(BOT_PREFIX):]

        text_split = text.strip().split(' ')
        cmd = None
        command = None
        args = ''
        if len(text_split) > 1:
            command = (text_split[0] + '_' + text_split[1]).lower()
            if command in self.commands:
                cmd = command
                args = ' '.join(text_split[2:])

        if not cmd:
            command = text_split[0].lower()
            args = ' '.join(text_split[1:])
            if command in self.commands:
                cmd = command
                if len(text_split) > 1:
                    args = ' '.join(text_split[1:])

        if command == BOT_PREFIX:  # we did "!!" so recall the last command
            if len(self.cmd_history):
                cmd, args = self.cmd_history[-1]
            else:
                return False  # no command in history
        elif command.isdigit():  # we did "!#" so we recall the specified command
            index = int(command)
            if len(self.cmd_history) >= index:
                cmd, args = self.cmd_history[-index]
            else:
                return False  # no command in history

        if (cmd, args) in self.cmd_history:
            self.cmd_history.remove((cmd, args))  # we readd it below

        logging.info("received command = %s matching [%s] with parameters [%s]" % (command, cmd, args))

        if cmd:
            def execute_and_send(template_name):
                try:
                    reply = self.commands[cmd](mess, args)

                    # integrated templating
                    if template_name:
                        reply = tenv().get_template(template_name + '.html').render(**reply)

                    # Reply should be all text at this point (See https://github.com/gbin/err/issues/96)
                    reply = str(reply)
                except Exception as e:
                    tb = traceback.format_exc()
                    logging.exception('An error happened while processing '
                                      'a message ("%s") from %s: %s"' %
                                      (text, jid, tb))
                    reply = self.MSG_ERROR_OCCURRED + ':\n %s' % e
                if reply:
                    if len(reply) > self.MESSAGE_SIZE_LIMIT:
                        reply = reply[:self.MESSAGE_SIZE_LIMIT - len(self.MESSAGE_SIZE_ERROR_MESSAGE)] + self.MESSAGE_SIZE_ERROR_MESSAGE
                    self.send_simple_reply(mess, reply, cmd in DIVERT_TO_PRIVATE)

            usr = str(get_jid_from_message(mess))
            typ = mess.getType()
            if cmd not in ACCESS_CONTROLS:
                ACCESS_CONTROLS[cmd] = ACCESS_CONTROLS_DEFAULT

            if 'allowusers' in ACCESS_CONTROLS[cmd] and usr not in ACCESS_CONTROLS[cmd]['allowusers']:
                self.send_simple_reply(mess, "You're not allowed to access this command from this user")
                return False
            if 'denyusers' in ACCESS_CONTROLS[cmd] and usr in ACCESS_CONTROLS[cmd]['denyusers']:
                self.send_simple_reply(mess, "You're not allowed to access this command from this user")
                return False
            if typ == 'groupchat':
                stripped = mess.getFrom().getStripped()
                if 'allowmuc' in ACCESS_CONTROLS[cmd] and ACCESS_CONTROLS[cmd]['allowmuc'] is False:
                    self.send_simple_reply(mess, "You're not allowed to access this command from a chatroom")
                    return False
                if 'allowrooms' in ACCESS_CONTROLS[cmd] and stripped not in ACCESS_CONTROLS[cmd]['allowrooms']:
                    self.send_simple_reply(mess, "You're not allowed to access this command from this room")
                    return False
                if 'denyrooms' in ACCESS_CONTROLS[cmd] and stripped in ACCESS_CONTROLS[cmd]['denyrooms']:
                    self.send_simple_reply(mess, "You're not allowed to access this command from this room")
                    return False
            else:
                if 'allowprivate' in ACCESS_CONTROLS[cmd] and ACCESS_CONTROLS[cmd]['allowprivate'] is False:
                    self.send_simple_reply(mess, "You're not allowed to access this command via private message to me")
                    return False

            f = self.commands[cmd]

            if f._err_command_admin_only:
                if typ == 'groupchat':
                    self.send_simple_reply(mess, 'You cannot administer the bot from a chatroom, message the bot directly')
                    return False
                if usr not in BOT_ADMINS:
                    self.send_simple_reply(mess, 'You cannot administer the bot from this user %s.' % usr)
                    return False
                if BOT_ASYNC:
                    self.thread_pool.wait() # If it is an admin command, wait that the queue is completely depleted so we don't have strange concurrency issues on load/unload/updates etc ...

            if f._err_command_historize:
                self.cmd_history.append((cmd, args)) # add it to the history only if it is authorized to be so

            # Don't check for None here as None can be a valid argument to split.
            # '' was chosen as default argument because this isn't a valid argument to split()
            if f._err_command_split_args_with != '':
                args = args.split(f._err_command_split_args_with)
            if BOT_ASYNC:
                wr = WorkRequest(execute_and_send, [f._err_command_template])
                self.thread_pool.putRequest(wr)
                if f._err_command_admin_only:
                    self.thread_pool.wait()  # Again wait for the completion before accepting a new command that could generate weird concurrency issues
            else:
                execute_and_send(f._err_command_template)

        else:
            logging.debug("Command not found")
            if surpress_cmd_not_found:
                logging.debug("Surpressing command not found feedback")
            else:
                reply = self.unknown_command(mess, command, args)
                if reply is None:
                    reply = self.MSG_UNKNOWN_COMMAND % {'command': command}
                if reply:
                    self.send_simple_reply(mess, reply)

        return True
Esempio n. 30
0
File: base.py Progetto: poirier/err
    def callback_message(self, conn, mess):
        """
        Needs to return False if we want to stop further treatment
        """
        # Prepare to handle either private chats or group chats
        type = mess.getType()
        jid = mess.getFrom()
        props = mess.getProperties()
        text = mess.getBody()
        username = get_sender_username(mess)

        if type not in ("groupchat", "chat"):
            logging.debug("unhandled message type %s" % mess)
            return False

        logging.debug("*** props = %s" % props)
        logging.debug("*** jid = %s" % jid)
        logging.debug("*** username = %s" % username)
        logging.debug("*** type = %s" % type)
        logging.debug("*** text = %s" % text)

        # If a message format is not supported (eg. encrypted),
        # txt will be None
        if not text: return False

        if not text.startswith(BOT_PREFIX):
            return True

        text = text[1:]
        text_split = text.strip().split(' ')

        cmd = None
        command = None
        args = ''
        if len(text_split) > 1:
            command = (text_split[0] + '_' + text_split[1]).lower()
            if self.commands.has_key(command):
                cmd = command
                args = ' '.join(text_split[2:])

        if not cmd:
            command = text_split[0].lower()
            args = ' '.join(text_split[1:])
            if self.commands.has_key(command):
                cmd = command
                if len(text_split) > 1:
                    args = ' '.join(text_split[1:])

        if command == BOT_PREFIX: # we did "!!" so recall the last command
            if len(self.cmd_history):
                cmd, args = self.cmd_history[-1]
            else:
                return False # no command in history
        elif command.isdigit(): # we did "!#" so we recall the specified command
            index = int(command)
            if len(self.cmd_history) >= index:
                cmd, args = self.cmd_history[-index]
            else:
                return False # no command in history

        if (cmd, args) in self.cmd_history:
            self.cmd_history.remove((cmd, args)) # we readd it below

        logging.info("received command = %s matching [%s] with parameters [%s]" % (command, cmd, args))

        if cmd:
            def execute_and_send(template_name):
                try:
                    reply = self.commands[cmd](mess, args)

                    # integrated templating
                    if template_name:
                        reply = tenv().get_template(template_name + '.html').render(**reply)

                except Exception, e:
                    logging.exception(u'An error happened while processing '\
                                      u'a message ("%s") from %s: %s"' %
                                      (text, jid, traceback.format_exc(e)))
                    reply = self.MSG_ERROR_OCCURRED + ':\n %s' % e
                if reply:
                    if len(reply) > self.MESSAGE_SIZE_LIMIT:
                        reply = reply[:self.MESSAGE_SIZE_LIMIT - len(self.MESSAGE_SIZE_ERROR_MESSAGE)] + self.MESSAGE_SIZE_ERROR_MESSAGE
                    self.send_simple_reply(mess, reply, cmd in DIVERT_TO_PRIVATE)

            f = self.commands[cmd]

            if f._err_command_admin_only:
                if mess.getType() == 'groupchat':
                    self.send_simple_reply(mess, 'You cannot administer the bot from a chatroom, message the bot directly')
                    return False
                usr = get_jid_from_message(mess)
                if usr not in BOT_ADMINS:
                    self.send_simple_reply(mess, 'You cannot administer the bot from this user %s.' % usr)
                    return False
                if BOT_ASYNC:
                    self.thread_pool.wait() # If it is an admin command, wait that the queue is completely depleted so we don't have strange concurrency issues on load/unload/updates etc ...

            if f._err_command_historize:
                self.cmd_history.append((cmd, args)) # add it to the history only if it is authorized to be so

            if f._err_command_split_args_with:
                args = args.split(f._err_command_split_args_with)
            if BOT_ASYNC:
                wr = WorkRequest(execute_and_send, [f._err_command_template]) #execute_and_send(f._err_command_template)
                self.thread_pool.putRequest(wr)
                if f._err_command_admin_only:
                    self.thread_pool.wait() # Again wait for the completion before accepting a new command that could generate weird concurrency issues
            else:
                execute_and_send(f._err_command_template)
Esempio n. 31
0
File: base.py Progetto: Dafvid/err
    def callback_message(self, mess):
        """
        Needs to return False if we want to stop further treatment
        """
        # Prepare to handle either private chats or group chats
        type_ = mess.type
        jid = mess.frm
        text = mess.body
        username = get_sender_username(mess)
        user_cmd_history = self.cmd_history[username]

        if mess.delayed:
            log.debug("Message from history, ignore it")
            return False

        if type_ not in ("groupchat", "chat"):
            log.debug("unhandled message type %s" % mess)
            return False

        # Ignore messages from ourselves. Because it isn't always possible to get the
        # real JID from a MUC participant (including ourself), matching the JID against
        # ourselves isn't enough (see https://github.com/gbin/err/issues/90 for
        # background discussion on this). Matching against CHATROOM_FN isn't technically
        # correct in all cases because a MUC could give us another nickname, but it
        # covers 99% of the MUC cases, so it should suffice for the time being.
        if (jid.bare_match(self.jid) or
            type_ == "groupchat" and mess.nick == self.bot_config.CHATROOM_FN):  # noqa
                log.debug("Ignoring message from self")
                return False

        log.debug("*** jid = %s" % jid)
        log.debug("*** username = %s" % username)
        log.debug("*** type = %s" % type_)
        log.debug("*** text = %s" % text)

        # If a message format is not supported (eg. encrypted),
        # txt will be None
        if not text:
            return False

        surpress_cmd_not_found = False

        prefixed = False  # Keeps track whether text was prefixed with a bot prefix
        only_check_re_command = False  # Becomes true if text is determed to not be a regular command
        tomatch = text.lower() if self.bot_config.BOT_ALT_PREFIX_CASEINSENSITIVE else text
        if len(self.bot_config.BOT_ALT_PREFIXES) > 0 and tomatch.startswith(self.bot_alt_prefixes):
            # Yay! We were called by one of our alternate prefixes. Now we just have to find out
            # which one... (And find the longest matching, in case you have 'err' and 'errbot' and
            # someone uses 'errbot', which also matches 'err' but would leave 'bot' to be taken as
            # part of the called command in that case)
            prefixed = True
            longest = 0
            for prefix in self.bot_alt_prefixes:
                l = len(prefix)
                if tomatch.startswith(prefix) and l > longest:
                    longest = l
            log.debug("Called with alternate prefix '{}'".format(text[:longest]))
            text = text[longest:]

            # Now also remove the separator from the text
            for sep in self.bot_config.BOT_ALT_PREFIX_SEPARATORS:
                # While unlikely, one may have separators consisting of
                # more than one character
                l = len(sep)
                if text[:l] == sep:
                    text = text[l:]
        elif type_ == "chat" and self.bot_config.BOT_PREFIX_OPTIONAL_ON_CHAT:
            log.debug("Assuming '%s' to be a command because BOT_PREFIX_OPTIONAL_ON_CHAT is True" % text)
            # In order to keep noise down we surpress messages about the command
            # not being found, because it's possible a plugin will trigger on what
            # was said with trigger_message.
            surpress_cmd_not_found = True
        elif not text.startswith(self.bot_config.BOT_PREFIX):
            only_check_re_command = True
        if text.startswith(self.bot_config.BOT_PREFIX):
            text = text[len(self.bot_config.BOT_PREFIX):]
            prefixed = True

        text = text.strip()
        text_split = text.split(' ')
        cmd = None
        command = None
        args = ''
        if not only_check_re_command:
            if len(text_split) > 1:
                command = (text_split[0] + '_' + text_split[1]).lower()
                if command in self.commands:
                    cmd = command
                    args = ' '.join(text_split[2:])

            if not cmd:
                command = text_split[0].lower()
                args = ' '.join(text_split[1:])
                if command in self.commands:
                    cmd = command
                    if len(text_split) > 1:
                        args = ' '.join(text_split[1:])

            if command == self.bot_config.BOT_PREFIX:  # we did "!!" so recall the last command
                if len(user_cmd_history):
                    cmd, args = user_cmd_history[-1]
                else:
                    return False  # no command in history
            elif command.isdigit():  # we did "!#" so we recall the specified command
                index = int(command)
                if len(user_cmd_history) >= index:
                    cmd, args = user_cmd_history[-index]
                else:
                    return False  # no command in history

        # Try to match one of the regex commands if the regular commands produced no match
        matched_on_re_command = False
        if not cmd:
            if prefixed:
                commands = self.re_commands
            else:
                commands = {k: self.re_commands[k] for k in self.re_commands
                            if not self.re_commands[k]._err_command_prefix_required}

            for name, func in commands.items():
                if func._err_command_matchall:
                    match = list(func._err_command_re_pattern.finditer(text))
                else:
                    match = func._err_command_re_pattern.search(text)
                if match:
                    log.debug("Matching '{}' against '{}' produced a match"
                              .format(text, func._err_command_re_pattern.pattern))
                    matched_on_re_command = True
                    self._process_command(mess, name, text, match)
                else:
                    log.debug("Matching '{}' against '{}' produced no match"
                              .format(text, func._err_command_re_pattern.pattern))
        if matched_on_re_command:
            return True

        if cmd:
            self._process_command(mess, cmd, args, match=None)
        elif not only_check_re_command:
            log.debug("Command not found")
            if surpress_cmd_not_found:
                log.debug("Surpressing command not found feedback")
            else:
                reply = self.unknown_command(mess, command, args)
                if reply is None:
                    reply = self.MSG_UNKNOWN_COMMAND % {'command': command}
                if reply:
                    self.send_simple_reply(mess, reply)
        return True
Esempio n. 32
0
File: base.py Progetto: kunaldeo/err
    def callback_message(self, conn, mess):
        """
        Needs to return False if we want to stop further treatment
        """
        # Prepare to handle either private chats or group chats
        type = mess.getType()
        jid = mess.getFrom()
        text = mess.getBody()
        username = get_sender_username(mess)
        user_cmd_history = self.cmd_history[username];

        if mess.isDelayed():
            logging.debug("Message from history, ignore it")
            return False

        if type not in ("groupchat", "chat"):
            logging.debug("unhandled message type %s" % mess)
            return False

        logging.debug("*** jid = %s" % jid)
        logging.debug("*** username = %s" % username)
        logging.debug("*** type = %s" % type)
        logging.debug("*** text = %s" % text)

        # If a message format is not supported (eg. encrypted),
        # txt will be None
        if not text:
            return False

        surpress_cmd_not_found = False

        tomatch = text.lower() if BOT_ALT_PREFIX_CASEINSENSITIVE else text
        if len(BOT_ALT_PREFIXES) > 0 and tomatch.startswith(self.bot_alt_prefixes):
            # Yay! We were called by one of our alternate prefixes. Now we just have to find out
            # which one... (And find the longest matching, in case you have 'err' and 'errbot' and
            # someone uses 'errbot', which also matches 'err' but would leave 'bot' to be taken as
            # part of the called command in that case)
            longest = 0
            for prefix in self.bot_alt_prefixes:
                l = len(prefix)
                if tomatch.startswith(prefix) and l > longest:
                    longest = l
            text = text[longest:]

            # Now also remove the separator from the text
            for sep in BOT_ALT_PREFIX_SEPARATORS:
                # While unlikely, one may have separators consisting of
                # more than one character
                l = len(sep)
                if text[:l] == sep:
                    text = text[l:]
        elif type == "chat" and BOT_PREFIX_OPTIONAL_ON_CHAT:
            logging.debug("Assuming '%s' to be a command because BOT_PREFIX_OPTIONAL_ON_CHAT is True" % text)
            # In order to keep noise down we surpress messages about the command
            # not being found, because it's possible a plugin will trigger on what
            # was said with trigger_message.
            surpress_cmd_not_found = True
        elif not text.startswith(BOT_PREFIX):
            return True
        if text.startswith(BOT_PREFIX):
            text = text[len(BOT_PREFIX):]

        text_split = text.strip().split(' ')
        cmd = None
        command = None
        args = ''
        if len(text_split) > 1:
            command = (text_split[0] + '_' + text_split[1]).lower()
            if command in self.commands:
                cmd = command
                args = ' '.join(text_split[2:])

        if not cmd:
            command = text_split[0].lower()
            args = ' '.join(text_split[1:])
            if command in self.commands:
                cmd = command
                if len(text_split) > 1:
                    args = ' '.join(text_split[1:])

        if command == BOT_PREFIX:  # we did "!!" so recall the last command
            if len(user_cmd_history):
                cmd, args = user_cmd_history[-1]
            else:
                return False  # no command in history
        elif command.isdigit():  # we did "!#" so we recall the specified command
            index = int(command)
            if len(user_cmd_history) >= index:
                cmd, args = user_cmd_history[-index]
            else:
                return False  # no command in history

        if (cmd, args) in user_cmd_history:
            user_cmd_history.remove((cmd, args))  # we readd it below

        if cmd:
            logging.info("received command = %s matching [%s] with parameters [%s]" % (command, cmd, args))

            access, accessError = self.checkCommandAccess(mess, cmd)
            if not access:
                if not HIDE_RESTRICTED_ACCESS:
                    self.send_simple_reply(mess, accessError)
                return False

            f = self.commands[cmd]

            if f._err_command_admin_only and BOT_ASYNC:
                    self.thread_pool.wait()  # If it is an admin command, wait that the queue is completely depleted so we don't have strange concurrency issues on load/unload/updates etc ...

            if f._err_command_historize:
                user_cmd_history.append((cmd, args))  # add it to the history only if it is authorized to be so

            # Don't check for None here as None can be a valid argument to split.
            # '' was chosen as default argument because this isn't a valid argument to split()
            if f._err_command_split_args_with != '':
                args = args.split(f._err_command_split_args_with)
            if BOT_ASYNC:
                wr = WorkRequest(self._execute_and_send,
                                 [], {'cmd': cmd, 'args': args, 'mess': mess, 'jid': jid,
                                      'template_name': f._err_command_template})
                self.thread_pool.putRequest(wr)
                if f._err_command_admin_only:
                    self.thread_pool.wait()  # Again wait for the completion before accepting a new command that could generate weird concurrency issues
            else:
                self._execute_and_send(cmd=cmd, args=args, mess=mess, jid=jid,
                                       template_name=f._err_command_template)

        else:
            logging.debug("Command not found")
            if surpress_cmd_not_found:
                logging.debug("Surpressing command not found feedback")
            else:
                reply = self.unknown_command(mess, command, args)
                if reply is None:
                    reply = self.MSG_UNKNOWN_COMMAND % {'command': command}
                if reply:
                    self.send_simple_reply(mess, reply)

        return True
Esempio n. 33
0
	def slap(self, mess, args):
		"""Let the bot slap people in the chatroom in an piratelike manner"""
		return "{0} slaps {1} around a bit with a large trout.".format(get_sender_username(mess), args)