Skip to content

Commit

Permalink
[find, slap] Update to 4.0 per issue #276
Browse files Browse the repository at this point in the history
  • Loading branch information
embolalia committed Jun 9, 2013
1 parent b0de0e1 commit aa8e7a7
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 49 deletions.
94 changes: 52 additions & 42 deletions willie/modules/find.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,50 +13,70 @@

import re
from willie.tools import Nick
from willie.module import rule, priority

def setup(willie):
willie.memory['find_lines'] = dict()

def collectlines(willie, trigger):

def setup(bot):
bot.memory['find_lines'] = dict()


@rule('.*')
@priority('low')
def collectlines(bot, trigger):
"""Create a temporary log of what people say"""

# Don't log things in PM
if not trigger.sender.startswith('#'):
return

# Add a log for the channel and nick, if there isn't already one
if trigger.sender not in willie.memory['find_lines']:
willie.memory['find_lines'][trigger.sender] = dict()
if Nick(trigger.nick) not in willie.memory['find_lines'][trigger.sender]:
willie.memory['find_lines'][trigger.sender][Nick(trigger.nick)] = list()
if trigger.sender not in bot.memory['find_lines']:
bot.memory['find_lines'][trigger.sender] = dict()
if Nick(trigger.nick) not in bot.memory['find_lines'][trigger.sender]:
bot.memory['find_lines'][trigger.sender][Nick(trigger.nick)] = list()

# Create a temporary list of the user's lines in a channel
templist = willie.memory['find_lines'][trigger.sender][Nick(trigger.nick)]
templist = bot.memory['find_lines'][trigger.sender][Nick(trigger.nick)]
line = trigger.group()
if line.startswith("s/"): # Don't remember substitutions
if line.startswith("s/"): # Don't remember substitutions
return
elif line.startswith("\x01ACTION"): # For /me messages
elif line.startswith("\x01ACTION"): # For /me messages
line = line[:-1]
templist.append(line)
else:
templist.append(line)

del templist[:-10] # Keep the log to 10 lines per person

willie.memory['find_lines'][trigger.sender][Nick(trigger.nick)] = templist
collectlines.rule = r'.*'
collectlines.priority = 'low'
del templist[:-10] # Keep the log to 10 lines per person

bot.memory['find_lines'][trigger.sender][Nick(trigger.nick)] = templist


def findandreplace(willie, trigger):
#Match nick, s/find/replace/flags. Flags and nick are optional, nick can be
#followed by comma or colon, anything after the first space after the third
#slash is ignored, you can escape slashes with backslashes, and if you want to
#search for an actual backslash followed by an actual slash, you're shit out of
#luck because this is the fucking regex of death as it is.
@rule(r"""(?:
(\S+) # Catch a nick in group 1
[:,]\s+)? # Followed by colon/comma and whitespace, if given
s/ # The literal s/
( # Group 2 is the thing to find
(?:\\/ | [^/])+ # One or more non-slashes or escaped slashes
)/( # Group 3 is what to replace with
(?:\\/ | [^/])* # One or more non-slashes or escaped slashes
)
(?:/(\S+))? # Optional slash, followed by group 4 (flags)
""")
@priority('high')
def findandreplace(bot, trigger):
# Don't bother in PM
if not trigger.sender.startswith('#'):
return

# Correcting other person vs self.
rnick = Nick(trigger.group(1) or trigger.nick)

search_dict = willie.memory['find_lines']
search_dict = bot.memory['find_lines']
# only do something if there is conversation to work with
if trigger.sender not in search_dict:
return
Expand All @@ -68,44 +88,44 @@ def findandreplace(willie, trigger):
rest = [trigger.group(2), trigger.group(3)]
rest[0] = rest[0].replace(r'\/', '/')
rest[1] = rest[1].replace(r'\/', '/')
me = False # /me command
me = False # /me command
flags = (trigger.group(4) or '')

# If g flag is given, replace all. Otherwise, replace once.
if 'g' in flags:
count = -1
else:
count = 1

# repl is a lambda function which performs the substitution. i flag turns
# off case sensitivity. re.U turns on unicode replacement.
if 'i' in flags:
regex = re.compile(re.escape(rest[0]),re.U|re.I)
repl = lambda s: re.sub(regex,rest[1],s,count == 1)
regex = re.compile(re.escape(rest[0]), re.U | re.I)
repl = lambda s: re.sub(regex, rest[1], s, count == 1)
else:
repl = lambda s: s.replace(rest[0],rest[1],count)
repl = lambda s: s.replace(rest[0], rest[1], count)

# Look back through the user's lines in the channel until you find a line
# where the replacement works
for line in reversed(search_dict[trigger.sender][rnick]):
if line.startswith("\x01ACTION"):
me = True # /me command
me = True # /me command
line = line[8:]
else:
me = False
new_phrase = repl(line)
if new_phrase != line: # we are done
if new_phrase != line: # we are done
break

if not new_phrase or new_phrase == line:
return # Didn't find anything
return # Didn't find anything

# Save the new "edited" message.
action = (me and '\x01ACTION ') or '' # If /me message, prepend \x01ACTION
action = (me and '\x01ACTION ') or '' # If /me message, prepend \x01ACTION
templist = search_dict[trigger.sender][rnick]
templist.append(action + new_phrase)
search_dict[trigger.sender][rnick] = templist
willie.memory['find_lines'] = search_dict
bot.memory['find_lines'] = search_dict

# output
if not me:
Expand All @@ -115,14 +135,4 @@ def findandreplace(willie, trigger):
else:
phrase = '%s %s' % (trigger.nick, new_phrase)

willie.say(phrase)

#Match nick, s/find/replace/flags. Flags and nick are optional, nick can be
#followed by comma or colon, anything after the first space after the third
#slash is ignored, you can escape slashes with backslashes, and if you want to
#search for an actual backslash followed by an actual slash, you're shit out of
#luck because this is the fucking regex of death as it is.
findandreplace.rule = r'(?:(\S+)[:,]\s+)?s/((?:\\/|[^/])+)/((?:\\/|[^/])*)(?:/(\S+))?'
findandreplace.priority = 'high'


bot.say(phrase)
14 changes: 7 additions & 7 deletions willie/modules/slap.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,22 @@
"""

import random
from willie.module import commands


@commands('slap', 'slaps')
def slap(willie, trigger):
""".slap <target> - Slaps <target>"""
text = trigger.group().split()
if len(text) < 2 or text[1].startswith('#'): return
if len(text) < 2 or text[1].startswith('#'):
return
if text[1] == willie.nick:
if (trigger.nick not in willie.config.admins):
text[1] = trigger.nick
else: text[1] = 'itself'
else:
text[1] = 'itself'
if text[1] in willie.config.admins:
if (trigger.nick not in willie.config.admins):
text[1] = trigger.nick
verb = random.choice(('slaps', 'kicks', 'destroys', 'annihilates', 'punches', 'roundhouse kicks', 'pwns', 'owns'))
willie.write(['PRIVMSG', trigger.sender, ' :\x01ACTION', verb, text[1], '\x01'])
slap.commands = ['slap', 'slaps']
slap.priority = 'medium'

if __name__ == '__main__':
print __doc__.strip()

0 comments on commit aa8e7a7

Please sign in to comment.