Ejemplo n.º 1
0
	def handler(self, **args):
		"""Allows someone to add material onto a factoid (that isn't locked) by
		saying "foo is also bar", for example"""
		import priv
		from irclib import Event
		from time import time
		target = self.return_to_sender(args)
		
		# args["text"] should look something like:
		#  "moobot: foo is also bar blatz qux"
		# Grab the factoid to change:
		factoid_key = self.strip_words(args["text"], 1).split(" is ")[0]
		# Grab the stuff to tack on:
		to_add = self.strip_words(args["text"], 1).split(" is also ")[1]

		# Check if the factoid is locked or not
		locked_by = FactoIds.getLockedBy(factoid_key)
		if locked_by == None:
			message = "Factoid '%s' does not exist." % factoid_key
			return Event("privmsg", "", target, [message])

		if priv.checkPriv(args["source"], "delete_priv") == 0 and (locked_by != "" and locked_by != args["source"]):
			message = "You do not have permission to delete factoid '%s." % factoid_key
			return Event("privmsg", "", target, [message])
		
		# Since we don't have delete_priv, we just delete and recreate the factoid
		orig_factoid = FactoIds.getValueByKey(factoid_key)
		new_factoid = orig_factoid + ", or " + to_add
		FactoIds.update(factoid_key, new_factoid, args["source"])
		return Event("privmsg", "", target, ["ok"])
Ejemplo n.º 2
0
    def handler(self, **args):
        """Allows someone to add material onto a factoid (that isn't locked) by
		saying "foo is also bar", for example"""
        import priv
        from irclib import Event
        from time import time
        target = self.return_to_sender(args)

        # args["text"] should look something like:
        #  "moobot: foo is also bar blatz qux"
        # Grab the factoid to change:
        factoid_key = self.strip_words(args["text"], 1).split(" is ")[0]
        # Grab the stuff to tack on:
        to_add = self.strip_words(args["text"], 1).split(" is also ")[1]

        # Check if the factoid is locked or not
        locked_by = FactoIds.getLockedBy(factoid_key)
        if locked_by == None:
            message = "Factoid '%s' does not exist." % factoid_key
            return Event("privmsg", "", target, [message])

        if priv.checkPriv(args["source"], "delete_priv") == 0 and (
                locked_by != "" and locked_by != args["source"]):
            message = "You do not have permission to delete factoid '%s." % factoid_key
            return Event("privmsg", "", target, [message])

        # Since we don't have delete_priv, we just delete and recreate the factoid
        orig_factoid = FactoIds.getValueByKey(factoid_key)
        new_factoid = orig_factoid + ", or " + to_add
        FactoIds.update(factoid_key, new_factoid, args["source"])
        return Event("privmsg", "", target, ["ok"])
Ejemplo n.º 3
0
	def handler(self, **args):
		"""Allows someone to alter material in a factoid by using a regular
		expression.  Invoked like: "moobot: foo =~ s/moo/bar/"."""
		import priv, re, time
		from irclib import Event
		target = self.return_to_sender(args)
		
		# Grab the factoid to change:
		# first, drop the bot name
		factoid_key = " ".join(args["text"].split()[1:])
		# Now split on " =~ " and take the left half
		factoid_key = factoid_key.split(" =~ ", 1)[0]
		
			
		locked_by = FactoIds.getLockedBy(factoid_key)
		if locked_by == None:
			message = "Factoid '%s' does not exist." % factoid_key
			return Event("privmsg", "", target, [message])

		# Check for the appropriate privilege (delete_priv, even
		# though we aren't deleting - we are modifying, and there
		# is no modify priv)
		if priv.checkPriv(args["source"], "delete_priv") == 0 and (locked_by != "" and locked_by != args["source"]):
			message = "You do not have permission to modify factoid '%s." % factoid_key
			return Event("privmsg", "", target, [message])

		# get the original factoid value
		factoid = FactoIds.getValueByKey(factoid_key)

		# Grab the regex(es) to apply
		# First split on =~, then split on spaces for the RHS
		regexes_str = args["text"].split(" =~ ", 1)[1]
		# Now we can't split just on spaces, because the regex itself
		# can have spaces in it.  We gotta grab each one individually
		# because a regex to get them all (potentially each having 
		# unique separators, like "s/foo/bar blatz/g s:moo:mooooo!:i
		# s%this%makes it hard to parse%".
		#
		# The basic algorithm is:
		# 1 - find out the separator character (2nd)
		# 2 - find the index of the third occurrence of this character
		# 3 - find the next space, chop off everything before it and
		#     append it to the regex_list
		regex_list = []
		# regex for removing leading spaces, compiling it first
		lead_spaces = re.compile("^\s+")
		while len(regexes_str) > 2:
			# Strip leading spaces first (so regexes with many spaces
			# between them don't mess things up when we assume the separator
			# is the second character)
			regexes_str = lead_spaces.sub("", regexes_str)
			# Separator = 2nd char
			separator = regexes_str[1]
			# Find it once, then use that as a low range
			# NOTE - if there is garbage at any point, ignore everything
			# after it
			second_sep = regexes_str.find(separator, 2)
			if second_sep == 0:	break
			third_sep = regexes_str.find(separator, second_sep+1)
			if third_sep == 0: break
			# now the space
			space_index = regexes_str.find(" ", third_sep)
			
			if space_index == -1:	# no space found
				regex_list.append(regexes_str)
				break
			else:
				regex_list.append(regexes_str[:space_index])
				regexes_str = regexes_str[space_index:]

		# apply each of the regexes in order
		# For now we are assuming all of the regexes are search and replace
		# s/foo/bar/[gi]
		ACCEPTABLE_PREFIXES = "sy"
		ACCEPTABLE_SUFFIXES = "gi"
		for regex_string in regex_list:
			# Split the regex into parts - strictly, we split on the second
			# character, as s:foo:bar: is valid as well
			try:
				parts = regex_string.split(regex_string[1])
			except IndexError:
				break

			# If we don't get four parts (even if the last is empty)
			# then it's not a valid regex - chastise them ... also,
			# if it's not one of the valid prefixes/suffixes, chastise them :)
			if len(parts) != 4 or \
			parts[0] not in ACCEPTABLE_PREFIXES:
				message = "Invalid regular expression: " + regex_string
				return Event("privmsg", "", target, [message])
			for letter in parts[3]:
				if letter not in ACCEPTABLE_SUFFIXES:
					message = "Invalid regular expression: " + regex_string
					return Event("privmsg", "", target, [message])

			# Get some flags before we compile a regex
			if "g" in parts[3]: count = 0
			else: count = 1
			if "i" in parts[3]: case_sensitive = 0
			else: case_sensitive = 1

			# Make a regex object for the first pattern
			try:
				re_str = parts[1]
				if case_sensitive:
					regex = re.compile(re_str)
				else:
					regex = re.compile(re_str, re.I)
			except re.error:
				message = "Invalid regular expression: " + regex_string
				return Event("privmsg", "", target, [message])
			
			# Actually perform the transformation
			if parts[0] == "s":
				factoid = regex.sub(parts[2], factoid)
			elif parts[0] == "y":
				message = "This regex not yet supported.  Sorry :("
				return Event("privmsg", "", target, [message])
				
					
		# When all the regexes are applied, store the factoid again
		# with the new date as the modification date.
		FactoIds.update(factoid_key, factoid, args["source"])
		return Event("privmsg", "", target, ["ok"])
Ejemplo n.º 4
0
	def handler(self, **args):
		""" gets the factoid_value field """
		import time
		from irclib import Event, nm_to_n

		# Store the ref
# 		ref = args["ref"]()

		# If we were /msg'ed this, /msg it back, otherwise send it to the
		# channel
		# (set up here because there are some rather early returns for the
		# continue handler types and whatnot)
		target = self.return_to_sender(args)

		factoid_key = args["text"]
		factoid_key = self.strip_words(factoid_key, 1) # removes "moobot: "

		# By default we want to parse the factoid value after grabbing it from
		# the db, but certain flags along the way may set this flag so that we
		# don't do so (e.g., "literal").
		dont_parse = 0

		# If we are called with something like "moobot: literal foo", we want
		# to strip the "literal" from it as that is not part of the
		# factoid, unless of course nothing follows "literal", in which
		# case we would be looking for the factoid for "literal" 
		if len(args["text"].split(" ")) > 1 and \
			args["text"].split(" ")[1] == "literal":
				dont_parse = 1	# set for later, when we spit the value back
				factoid_key = self.strip_words(factoid_key, 1)

		# Strip trailing ?'s and !'s (so asking for "moobot: foo?!?!?!???" is
		# the same as just asking for "moobot: foo" 
		factoid_key = self.strip_punctuation(factoid_key)

		text = FactoIds.getValueByKey(factoid_key, args["source"])

		# If the factoid doesn't exist, simply continue trying
		# to match with other handlers using the continue event type 
		if not text:
			return Event("continue", "", target, [""])

		### The new length stuff
		# Here we check to see if the total message length would be greater
		# than irclib.MESSAGE_SIZE_LIMIT, and if so, split it up accordingly
		# and return the requested one, or print out a warning.

		# Message format:
		# nickname!username@localhost privmsg #channel_name :factoid_text
# 		self.debug("%s!%s@%s" % (ref.connection.ircname, 
# 			ref.connection.username, ref.connection.localhost))
# #		msg_length = len(text) + len(" privmsg # :") + len(target) + \
# #			len(ref.connection.nickname) + len(ref.connection.username) + \
# #			len(ref.connection.localhost)
# #		self.debug(msg_length)


		# by default we will just say something to the target, but if the
		# factoid contains an <action> tag, we will make it an action
		# eventtype 
		eventtype="privmsg"

		# If the person says something like "moobot: literal foo", we don't
		# want to parse the factoid, we just want to spit it back in its raw
		# form.  Otherwise, we want to replace parentheses and pipes as well
		# as see if we need to change the eventtype 
		if not dont_parse:  # awkward, but supports the more general case,
							# instead of having to set a flag for every case
							# where we DO want to parse, only set a flag where
							# we do NOT parse
			
			# Strip spaces from the left-hand side
			text = text.lstrip()

			# Parse parentheses and pipes to come up with one random string
			# from many choices specified in the factoid 
			text = FactoIds.parseSar(text)

			# Replace $who and $nick with the person requesting the factoid
			text = text.replace("$who", nm_to_n(args["source"]))
			if args.has_key("channel"):
				text = text.replace("$chan", args["channel"])
			text = text.replace("$nick", nm_to_n(args["source"]))

			# If the new string (after previous replacements) begins with
			# "<action>" or "<reply>" (case insensitive), then we strip them
			# and possibly change the eventtype if necessary.  Otherwise, we
			# simply say "foo is bar" back to the target. 
			if text[:8].lower() == "<action>":
				eventtype="action"
				text = text[8:]
			elif text[:7].lower() == "<reply>":
				text = text[7:]
			else:
				text = factoid_key + " is " + text
	
		return Event(eventtype, "", target, [ text.strip() ])
Ejemplo n.º 5
0
    def handler(self, **args):
        """Allows someone to alter material in a factoid by using a regular
		expression.  Invoked like: "moobot: foo =~ s/moo/bar/"."""
        import priv, re, time
        from irclib import Event
        target = self.return_to_sender(args)

        # Grab the factoid to change:
        # first, drop the bot name
        factoid_key = " ".join(args["text"].split()[1:])
        # Now split on " =~ " and take the left half
        factoid_key = factoid_key.split(" =~ ", 1)[0]

        locked_by = FactoIds.getLockedBy(factoid_key)
        if locked_by == None:
            message = "Factoid '%s' does not exist." % factoid_key
            return Event("privmsg", "", target, [message])

        # Check for the appropriate privilege (delete_priv, even
        # though we aren't deleting - we are modifying, and there
        # is no modify priv)
        if priv.checkPriv(args["source"], "delete_priv") == 0 and (
                locked_by != "" and locked_by != args["source"]):
            message = "You do not have permission to modify factoid '%s." % factoid_key
            return Event("privmsg", "", target, [message])

        # get the original factoid value
        factoid = FactoIds.getValueByKey(factoid_key)

        # Grab the regex(es) to apply
        # First split on =~, then split on spaces for the RHS
        regexes_str = args["text"].split(" =~ ", 1)[1]
        # Now we can't split just on spaces, because the regex itself
        # can have spaces in it.  We gotta grab each one individually
        # because a regex to get them all (potentially each having
        # unique separators, like "s/foo/bar blatz/g s:moo:mooooo!:i
        # s%this%makes it hard to parse%".
        #
        # The basic algorithm is:
        # 1 - find out the separator character (2nd)
        # 2 - find the index of the third occurrence of this character
        # 3 - find the next space, chop off everything before it and
        #     append it to the regex_list
        regex_list = []
        # regex for removing leading spaces, compiling it first
        lead_spaces = re.compile("^\s+")
        while len(regexes_str) > 2:
            # Strip leading spaces first (so regexes with many spaces
            # between them don't mess things up when we assume the separator
            # is the second character)
            regexes_str = lead_spaces.sub("", regexes_str)
            # Separator = 2nd char
            separator = regexes_str[1]
            # Find it once, then use that as a low range
            # NOTE - if there is garbage at any point, ignore everything
            # after it
            second_sep = regexes_str.find(separator, 2)
            if second_sep == 0: break
            third_sep = regexes_str.find(separator, second_sep + 1)
            if third_sep == 0: break
            # now the space
            space_index = regexes_str.find(" ", third_sep)

            if space_index == -1:  # no space found
                regex_list.append(regexes_str)
                break
            else:
                regex_list.append(regexes_str[:space_index])
                regexes_str = regexes_str[space_index:]

        # apply each of the regexes in order
        # For now we are assuming all of the regexes are search and replace
        # s/foo/bar/[gi]
        ACCEPTABLE_PREFIXES = "sy"
        ACCEPTABLE_SUFFIXES = "gi"
        for regex_string in regex_list:
            # Split the regex into parts - strictly, we split on the second
            # character, as s:foo:bar: is valid as well
            try:
                parts = regex_string.split(regex_string[1])
            except IndexError:
                break

            # If we don't get four parts (even if the last is empty)
            # then it's not a valid regex - chastise them ... also,
            # if it's not one of the valid prefixes/suffixes, chastise them :)
            if len(parts) != 4 or \
            parts[0] not in ACCEPTABLE_PREFIXES:
                message = "Invalid regular expression: " + regex_string
                return Event("privmsg", "", target, [message])
            for letter in parts[3]:
                if letter not in ACCEPTABLE_SUFFIXES:
                    message = "Invalid regular expression: " + regex_string
                    return Event("privmsg", "", target, [message])

            # Get some flags before we compile a regex
            if "g" in parts[3]: count = 0
            else: count = 1
            if "i" in parts[3]: case_sensitive = 0
            else: case_sensitive = 1

            # Make a regex object for the first pattern
            try:
                re_str = parts[1]
                if case_sensitive:
                    regex = re.compile(re_str)
                else:
                    regex = re.compile(re_str, re.I)
            except re.error:
                message = "Invalid regular expression: " + regex_string
                return Event("privmsg", "", target, [message])

            # Actually perform the transformation
            if parts[0] == "s":
                factoid = regex.sub(parts[2], factoid)
            elif parts[0] == "y":
                message = "This regex not yet supported.  Sorry :("
                return Event("privmsg", "", target, [message])

        # When all the regexes are applied, store the factoid again
        # with the new date as the modification date.
        FactoIds.update(factoid_key, factoid, args["source"])
        return Event("privmsg", "", target, ["ok"])
Ejemplo n.º 6
0
    def handler(self, **args):
        """ gets the factoid_value field """
        import time
        from irclib import Event, nm_to_n

        # Store the ref
        # 		ref = args["ref"]()

        # If we were /msg'ed this, /msg it back, otherwise send it to the
        # channel
        # (set up here because there are some rather early returns for the
        # continue handler types and whatnot)
        target = self.return_to_sender(args)

        factoid_key = args["text"]
        factoid_key = self.strip_words(factoid_key, 1)  # removes "moobot: "

        # By default we want to parse the factoid value after grabbing it from
        # the db, but certain flags along the way may set this flag so that we
        # don't do so (e.g., "literal").
        dont_parse = 0

        # If we are called with something like "moobot: literal foo", we want
        # to strip the "literal" from it as that is not part of the
        # factoid, unless of course nothing follows "literal", in which
        # case we would be looking for the factoid for "literal"
        if len(args["text"].split(" ")) > 1 and \
         args["text"].split(" ")[1] == "literal":
            dont_parse = 1  # set for later, when we spit the value back
            factoid_key = self.strip_words(factoid_key, 1)

        # Strip trailing ?'s and !'s (so asking for "moobot: foo?!?!?!???" is
        # the same as just asking for "moobot: foo"
        factoid_key = self.strip_punctuation(factoid_key)

        text = FactoIds.getValueByKey(factoid_key, args["source"])

        # If the factoid doesn't exist, simply continue trying
        # to match with other handlers using the continue event type
        if not text:
            return Event("continue", "", target, [""])

        ### The new length stuff
        # Here we check to see if the total message length would be greater
        # than irclib.MESSAGE_SIZE_LIMIT, and if so, split it up accordingly
        # and return the requested one, or print out a warning.

        # Message format:
        # nickname!username@localhost privmsg #channel_name :factoid_text


# 		self.debug("%s!%s@%s" % (ref.connection.ircname,
# 			ref.connection.username, ref.connection.localhost))
# #		msg_length = len(text) + len(" privmsg # :") + len(target) + \
# #			len(ref.connection.nickname) + len(ref.connection.username) + \
# #			len(ref.connection.localhost)
# #		self.debug(msg_length)

# by default we will just say something to the target, but if the
# factoid contains an <action> tag, we will make it an action
# eventtype
        eventtype = "privmsg"

        # If the person says something like "moobot: literal foo", we don't
        # want to parse the factoid, we just want to spit it back in its raw
        # form.  Otherwise, we want to replace parentheses and pipes as well
        # as see if we need to change the eventtype
        if not dont_parse:  # awkward, but supports the more general case,
            # instead of having to set a flag for every case
            # where we DO want to parse, only set a flag where
            # we do NOT parse

            # Strip spaces from the left-hand side
            text = text.lstrip()

            # Parse parentheses and pipes to come up with one random string
            # from many choices specified in the factoid
            text = FactoIds.parseSar(text)

            # Replace $who and $nick with the person requesting the factoid
            text = text.replace("$who", nm_to_n(args["source"]))
            if args.has_key("channel"):
                text = text.replace("$chan", args["channel"])
            text = text.replace("$nick", nm_to_n(args["source"]))

            # If the new string (after previous replacements) begins with
            # "<action>" or "<reply>" (case insensitive), then we strip them
            # and possibly change the eventtype if necessary.  Otherwise, we
            # simply say "foo is bar" back to the target.
            if text[:8].lower() == "<action>":
                eventtype = "action"
                text = text[8:]
            elif text[:7].lower() == "<reply>":
                text = text[7:]
            else:
                text = factoid_key + " is " + text

        return Event(eventtype, "", target, [text.strip()])