mirror of
				https://github.com/Mikaela/Limnoria.git
				synced 2025-11-03 17:17:23 +01:00 
			
		
		
		
	SedRegex: spawn a single process to handle the whole history.
This is more efficient than spawning up to 1000 processes (assuming
Limnoria's default config).
From: ede85ca8b0
			
			
This commit is contained in:
		
							parent
							
								
									9e0db63b5b
								
							
						
					
					
						commit
						08764b85ef
					
				@ -30,6 +30,7 @@
 | 
			
		||||
###
 | 
			
		||||
 | 
			
		||||
from supybot.commands import *
 | 
			
		||||
from supybot.commands import ProcessTimeoutError
 | 
			
		||||
import supybot.plugins as plugins
 | 
			
		||||
import supybot.ircmsgs as ircmsgs
 | 
			
		||||
import supybot.callbacks as callbacks
 | 
			
		||||
@ -57,6 +58,9 @@ SED_REGEX = re.compile(r"^(?:(?P<nick>.+?)[:,] )?s(?P<delim>[^\w\s])(?P<pattern>
 | 
			
		||||
# Replace newlines and friends with things like literal "\n" (backslash and "n")
 | 
			
		||||
axe_spaces = utils.str.MultipleReplacer({'\n': '\\n', '\t': '\\t', '\r': '\\r'})
 | 
			
		||||
 | 
			
		||||
class SearchNotFound(Exception):
 | 
			
		||||
    pass
 | 
			
		||||
 | 
			
		||||
class SedRegex(callbacks.PluginRegexp):
 | 
			
		||||
    """History replacer using sed-style regex syntax."""
 | 
			
		||||
    threaded = True
 | 
			
		||||
@ -128,7 +132,25 @@ class SedRegex(callbacks.PluginRegexp):
 | 
			
		||||
        if not ircutils.isNick(str(target), strictRfc=True):
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        for m in iterable:
 | 
			
		||||
        regex_timeout = self.registryValue('processTimeout')
 | 
			
		||||
        try:
 | 
			
		||||
            message = process(self._replacer_process, irc, msg,
 | 
			
		||||
                    target, pattern, replacement, count, iterable,
 | 
			
		||||
                    timeout=regex_timeout, pn=self.name(), cn='replacer')
 | 
			
		||||
        except ProcessTimeoutError:
 | 
			
		||||
            irc.error(_("Search timed out."))
 | 
			
		||||
        except SearchNotFound:
 | 
			
		||||
            irc.error(_("Search not found in the last %i messages.") %
 | 
			
		||||
                len(irc.state.history))
 | 
			
		||||
        except Exception as e:
 | 
			
		||||
            if self.registryValue('displayErrors', msg.args[0]):
 | 
			
		||||
                irc.error('%s.%s: %s' % (e.__class__.__module__,
 | 
			
		||||
                    e.__class__.__name__, e))
 | 
			
		||||
        else:
 | 
			
		||||
            irc.reply(message, prefixNick=False)
 | 
			
		||||
 | 
			
		||||
    def _replacer_process(self, irc, msg, target, pattern, replacement, count, messages):
 | 
			
		||||
        for m in messages:
 | 
			
		||||
            if m.command in ('PRIVMSG', 'NOTICE') and \
 | 
			
		||||
                    ircutils.strEqual(m.args[0], msg.args[0]) and m.tagged('receivedBy') == irc:
 | 
			
		||||
                if target and m.nick != target:
 | 
			
		||||
@ -152,39 +174,27 @@ class SedRegex(callbacks.PluginRegexp):
 | 
			
		||||
                    messageprefix = msg.nick
 | 
			
		||||
                else:
 | 
			
		||||
                    messageprefix = '%s thinks %s' % (msg.nick, m.nick)
 | 
			
		||||
 | 
			
		||||
                try:
 | 
			
		||||
                    regex_timeout = self.registryValue('processTimeout')
 | 
			
		||||
                    replace_result = regexp_wrapper(text, pattern, timeout=regex_timeout, plugin_name=self.name(),
 | 
			
		||||
                                                    fcn_name='replacer')
 | 
			
		||||
                    if replace_result is True:
 | 
			
		||||
                    replace_result = pattern.search(text)
 | 
			
		||||
                    if replace_result:
 | 
			
		||||
                        if self.registryValue('boldReplacementText', msg.args[0]):
 | 
			
		||||
                            replacement = ircutils.bold(replacement)
 | 
			
		||||
                        subst = process(pattern.sub, replacement,
 | 
			
		||||
                                        text, count, timeout=regex_timeout)
 | 
			
		||||
                        subst = pattern.sub(replacement, text, count)
 | 
			
		||||
                        if action:  # If the message was an ACTION, prepend the nick back.
 | 
			
		||||
                            subst = '* %s %s' % (m.nick, subst)
 | 
			
		||||
 | 
			
		||||
                        subst = axe_spaces(subst)
 | 
			
		||||
 | 
			
		||||
                        irc.reply(_("%s meant to say: %s") %
 | 
			
		||||
                                    (messageprefix, subst), prefixNick=False)
 | 
			
		||||
                        return
 | 
			
		||||
                    elif replace_result is None:
 | 
			
		||||
                        # Abort on timeout instead of looking against older messages - this prevents
 | 
			
		||||
                        # replacing the wrong message when we get a one off timeout, which usually leads
 | 
			
		||||
                        # to very confusing results.
 | 
			
		||||
                        # This requires commit https://github.com/ProgVal/Limnoria/commit/b54d8f8073b4fca1787012b211337dc707cfea45
 | 
			
		||||
                        irc.error(_("Search timed out."), Raise=True)
 | 
			
		||||
                        return _("%s meant to say: %s") % \
 | 
			
		||||
                            (messageprefix, subst)
 | 
			
		||||
                except Exception as e:
 | 
			
		||||
                    self.log.warning(_("SedRegex error: %s"), e, exc_info=True)
 | 
			
		||||
                    if self.registryValue('displayErrors', msg.args[0]):
 | 
			
		||||
                        irc.error('%s.%s: %s' % (e.__class__.__module__, e.__class__.__name__, e))
 | 
			
		||||
                    return
 | 
			
		||||
                    raise
 | 
			
		||||
 | 
			
		||||
        self.log.debug(_("SedRegex: Search %r not found in the last %i messages of %s."),
 | 
			
		||||
                         msg.args[1], len(irc.state.history), msg.args[0])
 | 
			
		||||
        irc.error(_("Search not found in the last %i messages.") %
 | 
			
		||||
                    len(irc.state.history), Raise=True)
 | 
			
		||||
        raise SearchNotFound()
 | 
			
		||||
    replacer.__doc__ = SED_REGEX.pattern
 | 
			
		||||
 | 
			
		||||
Class = SedRegex
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user