Updated to use commands.py.

This commit is contained in:
Jeremy Fincher 2004-10-26 21:07:53 +00:00
parent 49019308d7
commit dffa1782d1
3 changed files with 77 additions and 186 deletions

View File

@ -34,20 +34,15 @@ users that can be retrieved later.
__revision__ = "$Id$" __revision__ = "$Id$"
import csv
import sets
import time import time
import getopt
import os.path
import operator import operator
from itertools import imap
import supybot.dbi as dbi import supybot.dbi as dbi
import supybot.log as log import supybot.log as log
import supybot.conf as conf import supybot.conf as conf
import supybot.utils as utils import supybot.utils as utils
import supybot.ircdb as ircdb import supybot.ircdb as ircdb
from supybot.commands import *
import supybot.ircmsgs as ircmsgs import supybot.ircmsgs as ircmsgs
import supybot.plugins as plugins import supybot.plugins as plugins
import supybot.privmsgs as privmsgs import supybot.privmsgs as privmsgs
@ -78,8 +73,6 @@ conf.registerGlobalValue(conf.supybot.plugins.Note.notify, 'autoSend',
class Ignores(registry.SpaceSeparatedListOfStrings): class Ignores(registry.SpaceSeparatedListOfStrings):
List = ircutils.IrcSet List = ircutils.IrcSet
conf.registerUserValue(conf.users.plugins.Note, 'ignores', Ignores([], ''))
class NoteRecord(dbi.Record): class NoteRecord(dbi.Record):
__fields__ = [ __fields__ = [
'frm', 'frm',
@ -219,92 +212,54 @@ class Note(callbacks.Privmsg):
except KeyError: except KeyError:
return None return None
def _validId(self, irc, id): def send(self, irc, msg, args, user, targets, text):
try:
id = id.lstrip('#')
return int(id)
except ValueError:
irc.error('That\'s not a valid note id.', Raise=True)
def send(self, irc, msg, args):
"""<recipient>,[<recipient>,[...]] <text> """<recipient>,[<recipient>,[...]] <text>
Sends a new note to the user specified. Multiple recipients may be Sends a new note to the user specified. Multiple recipients may be
specified by separating their names by commas, with *no* spaces specified by separating their names by commas.
between.
""" """
(names, text) = privmsgs.getArgs(args, required=2)
# Let's get the from user. # Let's get the from user.
try:
fromId = ircdb.users.getUserId(msg.prefix)
except KeyError:
irc.errorNotRegistered()
return
public = ircutils.isChannel(msg.args[0]) public = ircutils.isChannel(msg.args[0])
names = names.split(',')
ids = [self._getUserId(irc, name) for name in names]
badnames = []
# Make sure all targets are registered.
if None in ids:
for (id, name) in zip(ids, names):
if id is None:
badnames.append(name)
irc.errorNoUser(name=utils.commaAndify(badnames, And='or'))
return
# Make sure the sender isn't being ignored.
senderName = ircdb.users.getUser(fromId).name
for name in names:
ignores = self.userValue('ignores', name)
if ignores and senderName in ignores:
badnames.append(name)
if badnames:
irc.error('%s %s ignoring notes from you.' % \
(utils.commaAndify(badnames), utils.be(len(badnames))))
return
sent = [] sent = []
for toId in ids: for target in targets:
id = self.db.send(fromId, toId, public, text) id = self.db.send(user.id, target.id, public, text)
name = ircdb.users.getUser(toId).name s = 'note #%s sent to %s' % (id, target.name)
s = 'note #%s sent to %s' % (id, name)
sent.append(s) sent.append(s)
irc.reply(utils.commaAndify(sent).capitalize() + '.') irc.reply(utils.commaAndify(sent).capitalize() + '.')
send = wrap(send, ['user', commalist('otherUser'), 'text'])
def reply(self, irc, msg, args): def reply(self, irc, msg, args, user, id, text):
"""<id> <text> """<id> <text>
Sends a note in reply to <id>. Sends a note in reply to <id>.
""" """
if not args:
raise callbacks.ArgumentError
id = self._validId(irc, args[0])
args.append('(in reply to #%s)' % id)
note = self.db.get(id)
to = self.db.get(id).frm
self.db.setRead(id)
try: try:
args[0] = ircdb.users.getUser(to).name note = self.db.get(id)
except KeyError: except KeyError:
irc.error('Odd, the user you\'re replying to is no longer in the ' irc.error('That\'s not a note in my database.', Raise=True)
'database. You should notify my owner about this.') if note.to != user.id:
return irc.error('You may only reply to notes '
self.send(irc, msg, args) 'that have been sent to you.', Raise=True)
self.db.setRead(id)
text += ' (in reply to #%s)' % id
public = ircutils.isChannel(msg.args[0])
try:
target = ircdb.users.getUser(note.frm)
except KeyError:
irc.error('The user who sent you that note '
'is no longer in my user database.', Raise=True)
id = self.db.send(user.id, note.frm, public, text)
irc.reply('Note #%s sent to %s.' % (id, target.name))
reply = wrap(reply, [('id', 'note'), 'text'])
def unsend(self, irc, msg, args): def unsend(self, irc, msg, args, user, id):
"""<id> """<id>
Unsends the note with the id given. You must be the Unsends the note with the id given. You must be the
author of the note, and it must be unread. author of the note, and it must be unread.
""" """
try:
userid = ircdb.users.getUserId(msg.prefix)
except KeyError:
irc.errorNotRegistered()
return
id = privmsgs.getArgs(args)
id = self._validId(irc, id)
note = self.db.get(id) note = self.db.get(id)
if note.frm == userid: if note.frm == user.id:
if not note.read: if not note.read:
self.db.unsend(id) self.db.unsend(id)
irc.replySuccess() irc.replySuccess()
@ -312,6 +267,7 @@ class Note(callbacks.Privmsg):
irc.error('That note has been read already.') irc.error('That note has been read already.')
else: else:
irc.error('That note wasn\'t sent by you.') irc.error('That note wasn\'t sent by you.')
unsend = wrap(unsend, ['user', ('id', 'note')])
def _formatNote(self, note, to): def _formatNote(self, note, to):
elapsed = utils.timeElapsed(time.time() - note.at) elapsed = utils.timeElapsed(time.time() - note.at)
@ -323,58 +279,25 @@ class Note(callbacks.Privmsg):
recipient = ircdb.users.getUser(note.to).name recipient = ircdb.users.getUser(note.to).name
return '%s (Sent to %s %s ago)' % (note.text, recipient, elapsed) return '%s (Sent to %s %s ago)' % (note.text, recipient, elapsed)
def note(self, irc, msg, args): def note(self, irc, msg, args, user, id):
"""<note id> """<id>
Retrieves a single note by its unique note id. Use the 'note list' Retrieves a single note by its unique note id. Use the 'note list'
command to see what unread notes you have. command to see what unread notes you have.
""" """
try:
userid = ircdb.users.getUserId(msg.prefix)
except KeyError:
irc.errorNotRegistered()
return
id = privmsgs.getArgs(args)
id = self._validId(irc, id)
try: try:
note = self.db.get(id) note = self.db.get(id)
except KeyError: except KeyError:
irc.error('That\'s not a valid note id.') irc.error('That\'s not a valid note id.')
return return
if userid != note.frm and userid != note.to: if user.id != note.frm and user.id != note.to:
s = 'You may only retrieve notes you\'ve sent or received.' s = 'You may only retrieve notes you\'ve sent or received.'
irc.error(s) irc.error(s)
return return
newnote = self._formatNote(note, userid) newnote = self._formatNote(note, user.id)
irc.reply(newnote, private=(not note.public)) irc.reply(newnote, private=(not note.public))
self.db.setRead(id) self.db.setRead(id)
note = wrap(note, ['user', ('id', 'note')])
def ignore(self, irc, msg, args):
"""[--remove] <user>
Ignores all messages from <user>. If --remove is listed, remove <user>
from the list of users being ignored.
"""
remove = False
while '--remove' in args:
remove = True
args.remove('--remove')
user = privmsgs.getArgs(args)
try:
L = self.userValue('ignores', msg.prefix)
if remove:
try:
L.remove(user)
except (KeyError, ValueError):
irc.error('%s was not in your list of ignores.' %
utils.quoted(user))
return
else:
L.add(user)
self.setUserValue('ignores', msg.prefix, L)
irc.replySuccess()
except KeyError:
irc.errorNoUser()
def _formatNoteId(self, msg, note, sent=False): def _formatNoteId(self, msg, note, sent=False):
if note.public or not ircutils.isChannel(msg.args[0]): if note.public or not ircutils.isChannel(msg.args[0]):
@ -386,7 +309,7 @@ class Note(callbacks.Privmsg):
else: else:
return '#%s (private)' % note.id return '#%s (private)' % note.id
def list(self, irc, msg, args): def list(self, irc, msg, args, user, optlist):
"""[--{old,sent}] [--{from,to} <user>] """[--{old,sent}] [--{from,to} <user>]
Retrieves the ids of all your unread notes. If --old is given, list Retrieves the ids of all your unread notes. If --old is given, list
@ -394,40 +317,27 @@ class Note(callbacks.Privmsg):
--from is specified, only lists notes sent to you from <user>. If --from is specified, only lists notes sent to you from <user>. If
--to is specified, only lists notes sent by you to <user>. --to is specified, only lists notes sent by you to <user>.
""" """
options = ['old', 'sent', 'from=', 'to='] (sender, receiver, old, sent) = (None, None, False, False)
(optlist, rest) = getopt.getopt(args, '', options)
sender, receiver, old, sent = ('', '', False, False)
for (option, arg) in optlist: for (option, arg) in optlist:
if option == '--old': if option == 'old':
old = True old = True
if option == '--sent': if option == 'sent':
sent = True sent = True
if option == '--from': if option == 'from':
sender = arg sender = arg
if option == '--to': if option == 'to':
receiver = arg receiver = arg
sent = True sent = True
if old: if old:
return self._oldnotes(irc, msg, sender) return self._oldnotes(irc, msg, sender)
if sent: if sent:
return self._sentnotes(irc, msg, receiver) return self._sentnotes(irc, msg, receiver)
try:
userid = ircdb.users.getUserId(msg.prefix)
except KeyError:
irc.errorNotRegistered()
return
def p(note): def p(note):
return not note.read and note.to == userid return not note.read and note.to == user.id
if sender: if sender:
try: originalP = p
sender = ircdb.users.getUserId(sender) def p(note):
originalP = p return originalP(note) and note.frm == sender.id
def p(note):
return originalP(note) and note.frm == sender
except KeyError:
irc.errorNoUser()
return
notes = list(self.db.select(p)) notes = list(self.db.select(p))
if not notes: if not notes:
irc.reply('You have no unread notes.') irc.reply('You have no unread notes.')
@ -436,6 +346,9 @@ class Note(callbacks.Privmsg):
ids = [self._formatNoteId(msg, note) for note in notes] ids = [self._formatNoteId(msg, note) for note in notes]
ids = self._condense(ids) ids = self._condense(ids)
irc.reply(utils.commaAndify(ids)) irc.reply(utils.commaAndify(ids))
list = wrap(list, ['user', getopts({'old': '', 'sent': '',
'from': 'otherUser',
'to': 'otherUser'})])
def _condense(self, notes): def _condense(self, notes):
temp = {} temp = {}
@ -452,12 +365,12 @@ class Note(callbacks.Privmsg):
def _sentnotes(self, irc, msg, receiver): def _sentnotes(self, irc, msg, receiver):
try: try:
userid = ircdb.users.getUserId(msg.prefix) user = ircdb.users.getUser(msg.prefix)
except KeyError: except KeyError:
irc.errorNotRegistered() irc.errorNotRegistered()
return return
def p(note): def p(note):
return note.frm == userid return note.frm == user.id
if receiver: if receiver:
try: try:
receiver = ircdb.users.getUserId(receiver) receiver = ircdb.users.getUserId(receiver)
@ -479,21 +392,21 @@ class Note(callbacks.Privmsg):
def _oldnotes(self, irc, msg, sender): def _oldnotes(self, irc, msg, sender):
try: try:
userid = ircdb.users.getUserId(msg.prefix) user = ircdb.users.getUser(msg.prefix)
except KeyError: except KeyError:
irc.errorNotRegistered() irc.errorNotRegistered()
return return
def p(note): def p(note):
return note.to == userid and note.read return note.to == user.id and note.read
if sender: if sender:
try: try:
sender = ircdb.users.getUserId(sender) sender = ircdb.users.getUser(sender)
except KeyError: except KeyError:
irc.error('That user is not in my user database.') irc.error('That user is not in my user database.')
return return
originalP = p originalP = p
def p(note): def p(note):
return originalP(note) and note.frm == sender return originalP(note) and note.frm == sender.id
notes = list(self.db.select(p)) notes = list(self.db.select(p))
if not notes: if not notes:
irc.reply('I couldn\'t find any matching read notes for your user.') irc.reply('I couldn\'t find any matching read notes for your user.')

View File

@ -188,8 +188,6 @@ class ShrinkUrl(callbacks.PrivmsgCommandAndRegexp):
domain = webutils.getDomain(url) domain = webutils.getDomain(url)
s = '%s (at %s)' % (ircutils.bold(shorturl), domain) s = '%s (at %s)' % (ircutils.bold(shorturl), domain)
m = irc.reply(s, prefixName=False) m = irc.reply(s, prefixName=False)
if m is None:
print irc, irc.__class__
m.tag('shrunken') m.tag('shrunken')
shrinkSnarfer = urlSnarfer(shrinkSnarfer) shrinkSnarfer = urlSnarfer(shrinkSnarfer)

View File

@ -42,9 +42,9 @@ import supybot.conf as conf
import supybot.utils as utils import supybot.utils as utils
import supybot.world as world import supybot.world as world
import supybot.ircdb as ircdb import supybot.ircdb as ircdb
from supybot.commands import *
import supybot.plugins as plugins import supybot.plugins as plugins
import supybot.ircutils as ircutils import supybot.ircutils as ircutils
import supybot.privmsgs as privmsgs
import supybot.registry as registry import supybot.registry as registry
import supybot.callbacks as callbacks import supybot.callbacks as callbacks
@ -205,29 +205,26 @@ class WordStats(callbacks.Privmsg):
finally: finally:
self.queried = False self.queried = False
def add(self, irc, msg, args): def add(self, irc, msg, args, channel, word):
"""[<channel>] <word> """[<channel>] <word>
Keeps stats on <word> in <channel>. <channel> is only necessary if the Keeps stats on <word> in <channel>. <channel> is only necessary if the
message isn't sent in the channel itself. message isn't sent in the channel itself.
""" """
channel = privmsgs.getChannel(msg, args)
word = privmsgs.getArgs(args)
word = word.strip() word = word.strip()
if word.strip(nonAlphaNumeric) != word: if word.strip(nonAlphaNumeric) != word:
irc.error('<word> must not contain non-alphanumeric chars.') irc.error('<word> must not contain non-alphanumeric chars.')
return return
self.db.addWord(channel, word) self.db.addWord(channel, word)
irc.replySuccess() irc.replySuccess()
add = wrap(add, ['channel', 'somethingWithoutSpaces'])
def remove(self, irc, msg, args): def remove(self, irc, msg, args, channel, word):
"""[<channel>] <word> """[<channel>] <word>
Removes <word> from the list of words being tracked. If <channel> is Removes <word> from the list of words being tracked. If <channel> is
not specified, uses current channel. not specified, uses current channel.
""" """
channel = privmsgs.getChannel(msg, args)
word = privmsgs.getArgs(args)
words = self.db.getWords(channel) words = self.db.getWords(channel)
if words: if words:
if word in words: if word in words:
@ -236,12 +233,11 @@ class WordStats(callbacks.Privmsg):
else: else:
irc.error('%s doesn\'t look like a word I am keeping stats ' irc.error('%s doesn\'t look like a word I am keeping stats '
'on.' % utils.quoted(word)) 'on.' % utils.quoted(word))
return
else: else:
irc.error('I am not currently keeping any word stats.') irc.error('I am not currently keeping any word stats.')
return remove = wrap(remove, ['channel', 'somethingWithoutSpaces'])
def wordstats(self, irc, msg, args): def wordstats(self, irc, msg, args, channel, user, word):
"""[<channel>] [<user>] [<word>] """[<channel>] [<user>] [<word>]
With no arguments, returns the list of words that are being monitored With no arguments, returns the list of words that are being monitored
@ -252,9 +248,7 @@ class WordStats(callbacks.Privmsg):
<word> is given, <word> is assumed first and only if no stats are <word> is given, <word> is assumed first and only if no stats are
available for that word, do we assume it's <user>.) available for that word, do we assume it's <user>.)
""" """
channel = privmsgs.getChannel(msg, args) if not user and not word:
(arg1, arg2) = privmsgs.getArgs(args, required=0, optional=2)
if not arg1 and not arg2:
words = self.db.getWords(channel) words = self.db.getWords(channel)
if words: if words:
commaAndify = utils.commaAndify commaAndify = utils.commaAndify
@ -263,32 +257,22 @@ class WordStats(callbacks.Privmsg):
else: else:
irc.reply('I am not currently keeping any word stats.') irc.reply('I am not currently keeping any word stats.')
return return
elif arg1 and arg2: elif user and word:
user, word = (arg1, arg2)
try: try:
id = ircdb.users.getUserId(user) count = self.db.getWordCount(channel, user.id, word)
except KeyError: # Maybe it was a nick. Check the hostmask.
try:
hostmask = irc.state.nickToHostmask(user)
id = ircdb.users.getUserId(hostmask)
except KeyError:
irc.errorNoUser()
return
try:
count = self.db.getWordCount(channel, id, word)
except KeyError: except KeyError:
irc.error('I\'m not keeping stats on %s.' % irc.error('I\'m not keeping stats on %s.' %
utils.quoted(word)) utils.quoted(word))
return return
if count: if count:
s = '%s has said %s %s.' % \ s = '%s has said %s %s.' % \
(user, utils.quoted(word), utils.nItems('time', count)) (user.name, utils.quoted(word),
utils.nItems('time', count))
irc.reply(s) irc.reply(s)
else: else:
irc.error('%s has never said %s.' % irc.error('%s has never said %s.' %
(user, utils.quoted(word))) (user, utils.quoted(word)))
elif arg1 in WordDict.fromkeys(self.db.getWords(channel)): elif word in WordDict.fromkeys(self.db.getWords(channel)):
word = arg1
total = self.db.getTotalWordCount(channel, word) total = self.db.getTotalWordCount(channel, word)
if total == 0: if total == 0:
irc.reply('I\'m keeping stats on %s, but I haven\'t seen it ' irc.reply('I\'m keeping stats on %s, but I haven\'t seen it '
@ -323,27 +307,23 @@ class WordStats(callbacks.Privmsg):
s = '' s = ''
ret = '%s %s.%s' % (ret, utils.commaAndify(L), s) ret = '%s %s.%s' % (ret, utils.commaAndify(L), s)
irc.reply(ret) irc.reply(ret)
elif word:
irc.error('%r doesn\'t look like a word I\'m keeping stats '
'on or a user in my database.' % word)
else: else:
user = arg1
try: try:
id = ircdb.users.getUserId(user) L = ['%s: %s' % (utils.quoted(w), c)
for (w, c) in self.db.getUserWordCounts(channel,user.id)]
L.sort()
irc.reply(utils.commaAndify(L))
except KeyError: except KeyError:
irc.error('%s doesn\'t look like a word I\'m keeping stats ' irc.error('I have no wordstats for %s.' % user.name)
'on or a user in my database.' % utils.quoted(user)) wordstats = wrap(wordstats,
return ['channel',
try: optional('otherUser'),
L = ['%s: %s' % (utils.quoted(word), count) additional('somethingWithoutSpaces')])
for (word,count) in self.db.getUserWordCounts(channel,id)]
if L:
L.sort()
irc.reply(utils.commaAndify(L))
else:
irc.error('%s doesn\'t look like a word I\'m keeping stats'
' on or a user in my database.' %
utils.quoted(user))
return
except KeyError:
irc.error('I have no word stats for that person.')
Class = WordStats Class = WordStats
# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: # vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: