mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-11-20 01:19:26 +01:00
others/timeparse.py
This commit is contained in:
parent
6548085878
commit
0a2802f56e
3
TODO
3
TODO
@ -1,6 +1,9 @@
|
|||||||
Roughly in order of precedence (the closer to the front of the file,
|
Roughly in order of precedence (the closer to the front of the file,
|
||||||
the more likely it'll be done before next release):
|
the more likely it'll be done before next release):
|
||||||
|
|
||||||
|
* We should have a channel-global value in ircdb.IrcChannel for
|
||||||
|
ignoring unregistered users.
|
||||||
|
|
||||||
* It'd be nice to be able to use a backslash to continue lines in the
|
* It'd be nice to be able to use a backslash to continue lines in the
|
||||||
registry, so we could linewrap long strings or lists.
|
registry, so we could linewrap long strings or lists.
|
||||||
|
|
||||||
|
231
others/timeparse.py
Normal file
231
others/timeparse.py
Normal file
@ -0,0 +1,231 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2004, Mike Taylor
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are met:
|
||||||
|
#
|
||||||
|
# * Redistributions of source code must retain the above copyright notice,
|
||||||
|
# this list of conditions, and the following disclaimer.
|
||||||
|
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
# this list of conditions, and the following disclaimer in the
|
||||||
|
# documentation and/or other materials provided with the distribution.
|
||||||
|
# * Neither the name of the author of this software nor the name of
|
||||||
|
# contributors to this software may be used to endorse or promote products
|
||||||
|
# derived from this software without specific prior written consent.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
#
|
||||||
|
|
||||||
|
__author__ = "Mike Taylor <bear@code-bear.com>"
|
||||||
|
__copyright__ = "Copyright (c) 2004 Mike Taylor"
|
||||||
|
__license__ = "BSD"
|
||||||
|
__revision__ = "$Id$"
|
||||||
|
|
||||||
|
import os, string, re, time
|
||||||
|
|
||||||
|
RE_SPECIAL = r'(?P<special>^[in|last|next]+)\s+'
|
||||||
|
RE_UNITS = r'\s+(?P<units>[hour|minute|second|day|week|month|year]+)'
|
||||||
|
RE_QUNITS = r'(?P<qunits>[0-9]+[hmsdwmy])'
|
||||||
|
RE_MODIFIER = r'(?P<modifier>[from|before|after|ago|prior]+)\s+'
|
||||||
|
|
||||||
|
CRE_SPECIAL = re.compile(RE_SPECIAL, re.IGNORECASE)
|
||||||
|
CRE_UNITS = re.compile(RE_UNITS, re.IGNORECASE)
|
||||||
|
CRE_QUNITS = re.compile(RE_QUNITS, re.IGNORECASE)
|
||||||
|
CRE_MODIFIER = re.compile(RE_MODIFIER, re.IGNORECASE)
|
||||||
|
|
||||||
|
# Used to adjust the returned date before/after the source
|
||||||
|
|
||||||
|
_Modifiers = {'from': 1,
|
||||||
|
'before': -1,
|
||||||
|
'after': 1,
|
||||||
|
'ago': 1,
|
||||||
|
'prior': -1}
|
||||||
|
|
||||||
|
_Minute = 60
|
||||||
|
_Hour = 60 * _Minute
|
||||||
|
_Day = 24 * _Hour
|
||||||
|
_Week = 7 * _Day
|
||||||
|
_Month = 30 * _Day
|
||||||
|
_Year = 365 * _Day
|
||||||
|
|
||||||
|
# This looks hokey - but it is a nice simple way to get
|
||||||
|
# the proper unit value and it has the advantage that
|
||||||
|
# later I can morph it into something localized.
|
||||||
|
# Any trailing s will be removed before lookup.
|
||||||
|
|
||||||
|
_Units = {'second': 1,
|
||||||
|
'sec': 1,
|
||||||
|
's': 1,
|
||||||
|
'minute': _Minute,
|
||||||
|
'min': _Minute,
|
||||||
|
'm': _Minute,
|
||||||
|
'hour': _Hour,
|
||||||
|
'hr': _Hour,
|
||||||
|
'h': _Hour,
|
||||||
|
'day': _Day,
|
||||||
|
'dy': _Day,
|
||||||
|
'd': _Day,
|
||||||
|
'week': _Week,
|
||||||
|
'wk': _Week,
|
||||||
|
'w': _Week,
|
||||||
|
'month': _Month,
|
||||||
|
'mth': _Month,
|
||||||
|
'm': _Month,
|
||||||
|
'year': _Year,
|
||||||
|
'yr': _Year,
|
||||||
|
'y': _Year}
|
||||||
|
|
||||||
|
def _buildTime(sourceTime, quantity, modifier, units):
|
||||||
|
"""Take quantity, modifier and units strings and convert them
|
||||||
|
into values, calcuate the time and return the adjusted
|
||||||
|
sourceTime
|
||||||
|
"""
|
||||||
|
# print '[%s][%s][%s]' % (quantity, modifier, units)
|
||||||
|
|
||||||
|
q = int(quantity)
|
||||||
|
|
||||||
|
if _Modifiers.has_key(modifier):
|
||||||
|
q = q * _Modifiers[modifier]
|
||||||
|
|
||||||
|
if units[-1] == 's':
|
||||||
|
units = units[:-1]
|
||||||
|
|
||||||
|
if _Units.has_key(units):
|
||||||
|
u = _Units[units]
|
||||||
|
else:
|
||||||
|
u = 1
|
||||||
|
|
||||||
|
# print 'sourceTime [%d]' % sourceTime
|
||||||
|
# print 'quantity [%d]' % q
|
||||||
|
# print 'units [%d]' % u
|
||||||
|
|
||||||
|
return sourceTime + (q * u)
|
||||||
|
|
||||||
|
|
||||||
|
def parse(timeString, sourceTime=None):
|
||||||
|
"""Parse timeString and return the number of seconds from sourceTime
|
||||||
|
that the timeString expression represents.
|
||||||
|
|
||||||
|
This version of parse understands only the more basic of expressions
|
||||||
|
in this form:
|
||||||
|
|
||||||
|
<quantity> <units> <modifier> <target>
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
5 minutes from now
|
||||||
|
last week
|
||||||
|
2 hours before noon
|
||||||
|
|
||||||
|
Valid units - hour, minute, second, month, week, day and year
|
||||||
|
(including their plural forms)
|
||||||
|
Valid modifiers - from, before, after, ago, prior
|
||||||
|
"""
|
||||||
|
|
||||||
|
if sourceTime == None:
|
||||||
|
sourceTime = int(time.time())
|
||||||
|
else:
|
||||||
|
sourceTime = int(sourceTime)
|
||||||
|
|
||||||
|
quantity = ''
|
||||||
|
units = ''
|
||||||
|
modifier = ''
|
||||||
|
target = ''
|
||||||
|
|
||||||
|
s = string.strip(string.lower(timeString))
|
||||||
|
|
||||||
|
m = CRE_SPECIAL.search(s)
|
||||||
|
|
||||||
|
if m <> None:
|
||||||
|
target = 'now'
|
||||||
|
|
||||||
|
if m.group('special') == 'last':
|
||||||
|
modifier = 'before'
|
||||||
|
else:
|
||||||
|
modifier = 'from'
|
||||||
|
|
||||||
|
s = s[m.end('special'):]
|
||||||
|
|
||||||
|
m = CRE_UNITS.search(s)
|
||||||
|
|
||||||
|
if m <> None:
|
||||||
|
units = m.group('units')
|
||||||
|
quantity = s[:m.start('units')]
|
||||||
|
s = s[m.end('units'):]
|
||||||
|
|
||||||
|
else:
|
||||||
|
m = CRE_MODIFIER.search(s)
|
||||||
|
|
||||||
|
if m <> None:
|
||||||
|
modifier = m.group('modifier')
|
||||||
|
target = s[m.end('modifier'):]
|
||||||
|
s = s[:m.start('modifier'):]
|
||||||
|
|
||||||
|
m = CRE_UNITS.search(s)
|
||||||
|
|
||||||
|
if m <> None:
|
||||||
|
units = m.group('units')
|
||||||
|
quantity = s[:m.start('units')]
|
||||||
|
target = s[m.end('units'):]
|
||||||
|
|
||||||
|
return _buildTime(sourceTime, quantity, modifier, units)
|
||||||
|
|
||||||
|
def _test(text, value):
|
||||||
|
print text
|
||||||
|
|
||||||
|
v = parse(text)
|
||||||
|
|
||||||
|
print '\t%s\t%d\t%d' % ((v == value), value, v)
|
||||||
|
|
||||||
|
#
|
||||||
|
# TODO
|
||||||
|
#
|
||||||
|
# - make month unit adjustment aware of the actual number of days in each
|
||||||
|
# month between source and target
|
||||||
|
# - handle edge case where quantity and unit are merged: 5s for 5 sec
|
||||||
|
# - handle compound/nested quantites and modifiers
|
||||||
|
# - bring unit test over from prototype into this file
|
||||||
|
# - convert 'five' to 5 and also 'twenty five' to 25
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
start = int(time.time())
|
||||||
|
tests = { '5 minutes from now': start + 5 * _Minute,
|
||||||
|
'5 min from now': start + 5 * _Minute,
|
||||||
|
'in 5 minutes': start + 5 * _Minute,
|
||||||
|
'5 days from today': start + 5 * _Day,
|
||||||
|
'5 days before today': start - 5 * _Day,
|
||||||
|
'5 minutes': start + 5 * _Minute,
|
||||||
|
'5 min': start + 5 * _Minute,
|
||||||
|
'30 seconds from now': start + 30,
|
||||||
|
'30 sec from now': start + 30,
|
||||||
|
'30 seconds': start + 30,
|
||||||
|
'30 sec': start + 30,
|
||||||
|
'1 week': start + _Week,
|
||||||
|
'1 wk': start + _Week,
|
||||||
|
'1 week': start + _Week,
|
||||||
|
'5 days': start + 5 * _Day,
|
||||||
|
'1 year': start + _Year,
|
||||||
|
'2 years': start + 2 * _Year}
|
||||||
|
|
||||||
|
for test in tests.keys():
|
||||||
|
_test(test, tests[test])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -45,9 +45,12 @@ import time
|
|||||||
sys.path.append(os.pardir)
|
sys.path.append(os.pardir)
|
||||||
|
|
||||||
import supybot.conf as conf
|
import supybot.conf as conf
|
||||||
|
import supybot.utils as utils
|
||||||
import supybot.ircmsgs as ircmsgs
|
import supybot.ircmsgs as ircmsgs
|
||||||
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.schedule as schedule
|
||||||
import supybot.callbacks as callbacks
|
import supybot.callbacks as callbacks
|
||||||
|
|
||||||
conf.registerPlugin('Ctcp')
|
conf.registerPlugin('Ctcp')
|
||||||
@ -63,8 +66,13 @@ conf.registerGlobalValue(conf.supybot.abuse.flood.ctcp, 'maximum',
|
|||||||
conf.registerGlobalValue(conf.supybot.abuse.flood.ctcp, 'punishment',
|
conf.registerGlobalValue(conf.supybot.abuse.flood.ctcp, 'punishment',
|
||||||
registry.PositiveInteger(300, """Determines how many seconds the bot will
|
registry.PositiveInteger(300, """Determines how many seconds the bot will
|
||||||
ignore CTCP messages from users who flood it with CTCP messages."""))
|
ignore CTCP messages from users who flood it with CTCP messages."""))
|
||||||
|
conf.registerGlobalValue(conf.supybot.plugins.Ctcp, 'versionWait',
|
||||||
|
registry.PositiveInteger(10, """Determines how many seconds the bot will
|
||||||
|
wait after getting a version command (not a CTCP VERSION, but an actual
|
||||||
|
call of the command in this plugin named "version") before replying with
|
||||||
|
the results it has collected."""))
|
||||||
|
|
||||||
class Ctcp(callbacks.PrivmsgRegexp):
|
class Ctcp(callbacks.PrivmsgCommandAndRegexp):
|
||||||
public = False
|
public = False
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.__parent = super(Ctcp, self)
|
self.__parent = super(Ctcp, self)
|
||||||
@ -96,35 +104,77 @@ class Ctcp(callbacks.PrivmsgRegexp):
|
|||||||
s = '\x01%s\x01' % s
|
s = '\x01%s\x01' % s
|
||||||
irc.reply(s, notice=True, private=True, to=msg.nick)
|
irc.reply(s, notice=True, private=True, to=msg.nick)
|
||||||
|
|
||||||
def ping(self, irc, msg, match):
|
regexps = ('ctcpPing', 'ctcpVersion', 'ctcpUserinfo',
|
||||||
|
'ctcpTime', 'ctcpFinger', 'ctcpSource')
|
||||||
|
def ctcpPing(self, irc, msg, match):
|
||||||
"\x01PING (.*)\x01"
|
"\x01PING (.*)\x01"
|
||||||
self.log.info('Received CTCP PING from %s', msg.prefix)
|
self.log.info('Received CTCP PING from %s', msg.prefix)
|
||||||
self._reply(irc, msg, 'PING %s' % match.group(1))
|
self._reply(irc, msg, 'PING %s' % match.group(1))
|
||||||
|
|
||||||
def version(self, irc, msg, match):
|
def ctcpVersion(self, irc, msg, match):
|
||||||
"\x01VERSION\x01"
|
"\x01VERSION\x01"
|
||||||
self.log.info('Received CTCP VERSION from %s', msg.prefix)
|
self.log.info('Received CTCP VERSION from %s', msg.prefix)
|
||||||
self._reply(irc, msg, 'VERSION Supybot %s' % conf.version)
|
self._reply(irc, msg, 'VERSION Supybot %s' % conf.version)
|
||||||
|
|
||||||
def userinfo(self, irc, msg, match):
|
def ctcpUserinfo(self, irc, msg, match):
|
||||||
"\x01USERINFO\x01"
|
"\x01USERINFO\x01"
|
||||||
self.log.info('Received CTCP USERINFO from %s', msg.prefix)
|
self.log.info('Received CTCP USERINFO from %s', msg.prefix)
|
||||||
self._reply(irc, msg, 'USERINFO')
|
self._reply(irc, msg, 'USERINFO')
|
||||||
|
|
||||||
def time(self, irc, msg, match):
|
def ctcpTime(self, irc, msg, match):
|
||||||
"\x01TIME\x01"
|
"\x01TIME\x01"
|
||||||
self.log.info('Received CTCP TIME from %s' % msg.prefix)
|
self.log.info('Received CTCP TIME from %s' % msg.prefix)
|
||||||
self._reply(irc, msg, time.ctime())
|
self._reply(irc, msg, time.ctime())
|
||||||
|
|
||||||
def finger(self, irc, msg, match):
|
def ctcpFinger(self, irc, msg, match):
|
||||||
"\x01FINGER\x01"
|
"\x01FINGER\x01"
|
||||||
self.log.info('Received CTCP FINGER from %s' % msg.prefix)
|
self.log.info('Received CTCP FINGER from %s' % msg.prefix)
|
||||||
self._reply(irc, msg, 'Supybot, the best Python IRC bot in existence!')
|
self._reply(irc, msg, 'Supybot, the best Python IRC bot in existence!')
|
||||||
|
|
||||||
def source(self, irc, msg, match):
|
def ctcpSource(self, irc, msg, match):
|
||||||
"\x01SOURCE\x01"
|
"\x01SOURCE\x01"
|
||||||
self.log.info('Received CTCP SOURCE from %s' % msg.prefix)
|
self.log.info('Received CTCP SOURCE from %s' % msg.prefix)
|
||||||
self._reply(irc, msg, 'http://www.sourceforge.net/projects/supybot/')
|
self._reply(irc, msg, 'http://www.sourceforge.net/projects/supybot/')
|
||||||
|
|
||||||
|
def doNotice(self, irc, msg):
|
||||||
|
if ircmsgs.isCtcp(msg):
|
||||||
|
try:
|
||||||
|
(version, payload) = msg.args[1][1:-1].split(None, 1)
|
||||||
|
except ValueError:
|
||||||
|
return
|
||||||
|
if version == 'VERSION':
|
||||||
|
self.versions.setdefault(payload, []).append(msg.nick)
|
||||||
|
|
||||||
|
def version(self, irc, msg, args):
|
||||||
|
"""[<channel>] [--nicks]
|
||||||
|
|
||||||
|
Sends a CTCP VERSION to <channel>, returning the various
|
||||||
|
version strings returned. It waits for 10 seconds before returning
|
||||||
|
the versions received at that point. If --nicks is given, nicks are
|
||||||
|
associated with the version strings; otherwise, only the version
|
||||||
|
strings are given.
|
||||||
|
"""
|
||||||
|
self.versions = ircutils.IrcDict()
|
||||||
|
nicks = False
|
||||||
|
while '--nicks' in args:
|
||||||
|
nicks = True
|
||||||
|
args.remove('--nicks')
|
||||||
|
channel = privmsgs.getChannel(msg, args)
|
||||||
|
irc.queueMsg(ircmsgs.privmsg(channel, '\x01VERSION\x01'))
|
||||||
|
def doReply():
|
||||||
|
if self.versions:
|
||||||
|
L = []
|
||||||
|
for (reply, nicks) in self.versions.iteritems():
|
||||||
|
if nicks:
|
||||||
|
L.append('%s responded with %r' %
|
||||||
|
(utils.commaAndify(nicks), reply))
|
||||||
|
else:
|
||||||
|
L.append(reply)
|
||||||
|
irc.reply(utils.commaAndify(L))
|
||||||
|
else:
|
||||||
|
irc.reply('I received no version responses.')
|
||||||
|
wait = self.registryValue('versionWait')
|
||||||
|
schedule.addEvent(doReply, time.time()+wait)
|
||||||
|
|
||||||
Class = Ctcp
|
Class = Ctcp
|
||||||
# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78:
|
# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78:
|
||||||
|
@ -275,8 +275,7 @@ class Debian(callbacks.Privmsg,
|
|||||||
r = utils.perlReToPythonRe(arg)
|
r = utils.perlReToPythonRe(arg)
|
||||||
predicates.append(r.search)
|
predicates.append(r.search)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
irc.error('%r is not a valid regexp.' % arg)
|
irc.errorInvalid('regular expression', arg, Raise=True)
|
||||||
return
|
|
||||||
elif option == '--arch':
|
elif option == '--arch':
|
||||||
arg = '_%s.' % arg
|
arg = '_%s.' % arg
|
||||||
archPredicate = lambda s, arg=arg: (arg in s)
|
archPredicate = lambda s, arg=arg: (arg in s)
|
||||||
|
@ -194,8 +194,7 @@ class Dunno(callbacks.Privmsg):
|
|||||||
try:
|
try:
|
||||||
id = int(id)
|
id = int(id)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
irc.error('Invalid id: %r' % id)
|
irc.error('id', id, Raise=True)
|
||||||
return
|
|
||||||
dunno = self.db.get(channel, id)
|
dunno = self.db.get(channel, id)
|
||||||
if by != dunno.by:
|
if by != dunno.by:
|
||||||
cap = ircdb.makeChannelCapability(channel, 'op')
|
cap = ircdb.makeChannelCapability(channel, 'op')
|
||||||
@ -238,8 +237,7 @@ class Dunno(callbacks.Privmsg):
|
|||||||
try:
|
try:
|
||||||
id = int(id)
|
id = int(id)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
irc.error('%r is not a valid dunno id.' % id)
|
irc.errorInvalid('dunno id', id, Raise=True)
|
||||||
return
|
|
||||||
try:
|
try:
|
||||||
dunno = self.db.get(channel, id)
|
dunno = self.db.get(channel, id)
|
||||||
name = ircdb.users.getUser(dunno.by).name
|
name = ircdb.users.getUser(dunno.by).name
|
||||||
@ -268,18 +266,15 @@ class Dunno(callbacks.Privmsg):
|
|||||||
try:
|
try:
|
||||||
id = int(id)
|
id = int(id)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
irc.error('%r is not a valid dunno id.' % id)
|
irc.errorInvalid('dunno id', id, Raise=True)
|
||||||
return
|
|
||||||
try:
|
try:
|
||||||
_ = self.db.get(channel, id)
|
_ = self.db.get(channel, id)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
irc.error('There is no dunno #%s.' % id)
|
irc.error('There is no dunno #%s.' % id)
|
||||||
return
|
|
||||||
try:
|
try:
|
||||||
replacer = utils.perlReToReplacer(regexp)
|
replacer = utils.perlReToReplacer(regexp)
|
||||||
except:
|
except:
|
||||||
irc.error('%r is not a valid regular expression.' % regexp)
|
irc.errorInvalid('regular expression', regexp, Raise=True)
|
||||||
return
|
|
||||||
self.db.change(channel, id, replacer)
|
self.db.change(channel, id, replacer)
|
||||||
irc.replySuccess()
|
irc.replySuccess()
|
||||||
|
|
||||||
|
@ -171,8 +171,7 @@ class Factoids(plugins.ChannelDBHandler, callbacks.Privmsg):
|
|||||||
try:
|
try:
|
||||||
irc.reply(factoids[number-1])
|
irc.reply(factoids[number-1])
|
||||||
except IndexError:
|
except IndexError:
|
||||||
irc.error('That\'s not a valid number for that key.')
|
irc.errorInvalid('number for that key', number, Raise=True)
|
||||||
return
|
|
||||||
else:
|
else:
|
||||||
intro = self.registryValue('factoidPrefix', channel)
|
intro = self.registryValue('factoidPrefix', channel)
|
||||||
prefix = '%r %s' % (key, intro)
|
prefix = '%r %s' % (key, intro)
|
||||||
@ -214,8 +213,7 @@ class Factoids(plugins.ChannelDBHandler, callbacks.Privmsg):
|
|||||||
try:
|
try:
|
||||||
number = int(number)
|
number = int(number)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
irc.error('%s is not a valid number.' % number)
|
irc.errorInvalid('number', number, Raise=True)
|
||||||
return
|
|
||||||
else:
|
else:
|
||||||
number = 0
|
number = 0
|
||||||
factoids = self._lookupFactoid(channel, key)
|
factoids = self._lookupFactoid(channel, key)
|
||||||
@ -293,8 +291,7 @@ class Factoids(plugins.ChannelDBHandler, callbacks.Privmsg):
|
|||||||
try:
|
try:
|
||||||
(_, id) = results[number]
|
(_, id) = results[number]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
irc.error('Invalid factoid number.')
|
irc.errorInvalid('factoid number', number, Raise=True)
|
||||||
return
|
|
||||||
cursor.execute("DELETE FROM factoids WHERE id=%s", id)
|
cursor.execute("DELETE FROM factoids WHERE id=%s", id)
|
||||||
db.commit()
|
db.commit()
|
||||||
irc.replySuccess()
|
irc.replySuccess()
|
||||||
@ -370,15 +367,13 @@ class Factoids(plugins.ChannelDBHandler, callbacks.Privmsg):
|
|||||||
try:
|
try:
|
||||||
replacer = utils.perlReToReplacer(regexp)
|
replacer = utils.perlReToReplacer(regexp)
|
||||||
except ValueError, e:
|
except ValueError, e:
|
||||||
irc.error('Invalid regexp: %s' % e)
|
irc.errorInvalid('regular expression', regexp, str(e), Raise=True)
|
||||||
return
|
|
||||||
try:
|
try:
|
||||||
number = int(number)
|
number = int(number)
|
||||||
if number <= 0:
|
if number <= 0:
|
||||||
raise ValueError
|
raise ValueError
|
||||||
except ValueError:
|
except ValueError:
|
||||||
irc.error('Invalid key id.')
|
irc.errorInvalid('id', number, Raise=True)
|
||||||
return
|
|
||||||
db = self.getDb(channel)
|
db = self.getDb(channel)
|
||||||
cursor = db.cursor()
|
cursor = db.cursor()
|
||||||
cursor.execute("""SELECT factoids.id, factoids.fact
|
cursor.execute("""SELECT factoids.id, factoids.fact
|
||||||
|
@ -101,14 +101,12 @@ class Format(callbacks.Privmsg):
|
|||||||
try:
|
try:
|
||||||
fg = ircutils.mircColors[fg]
|
fg = ircutils.mircColors[fg]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
irc.error('%r is not a valid foreground color.' % fg)
|
irc.errorInvalid('foreground color', fg, Raise=True)
|
||||||
return
|
|
||||||
if bg is not None:
|
if bg is not None:
|
||||||
try:
|
try:
|
||||||
bg = ircutils.mircColors[bg]
|
bg = ircutils.mircColors[bg]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
irc.error('%r is not a valid background color.' % bg)
|
irc.errorInvalid('background color', bg, Raise=True)
|
||||||
return
|
|
||||||
irc.reply(ircutils.mircColor(text, fg=fg, bg=bg))
|
irc.reply(ircutils.mircColor(text, fg=fg, bg=bg))
|
||||||
|
|
||||||
def join(self, irc, msg, args):
|
def join(self, irc, msg, args):
|
||||||
@ -172,7 +170,7 @@ class Format(callbacks.Privmsg):
|
|||||||
try:
|
try:
|
||||||
size = int(size)
|
size = int(size)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
irc.error('%r is not a valid integer.' % size)
|
irc.errorInvalid('integer', size, Raise=True)
|
||||||
irc.reply(text[:size])
|
irc.reply(text[:size])
|
||||||
|
|
||||||
def field(self, irc, msg, args):
|
def field(self, irc, msg, args):
|
||||||
@ -187,11 +185,11 @@ class Format(callbacks.Privmsg):
|
|||||||
if index > 0:
|
if index > 0:
|
||||||
index -= 1
|
index -= 1
|
||||||
except ValueError:
|
except ValueError:
|
||||||
irc.error('%r is not a valid integer.' % number)
|
irc.errorInvalid('integer', number, Raise=True)
|
||||||
try:
|
try:
|
||||||
irc.reply(text.split()[index])
|
irc.reply(text.split()[index])
|
||||||
except IndexError:
|
except IndexError:
|
||||||
irc.error('That\'s not a valid field.')
|
irc.errorInvalid('field')
|
||||||
|
|
||||||
def format(self, irc, msg, args):
|
def format(self, irc, msg, args):
|
||||||
"""<format string> [<arg> ...]
|
"""<format string> [<arg> ...]
|
||||||
|
@ -252,8 +252,7 @@ class Herald(callbacks.Privmsg):
|
|||||||
try:
|
try:
|
||||||
changer = utils.perlReToReplacer(regexp)
|
changer = utils.perlReToReplacer(regexp)
|
||||||
except ValueError, e:
|
except ValueError, e:
|
||||||
irc.error('That\'s not a valid regexp: %s.' % e)
|
irc.errorInvalid('regular expression', regexp, str(e), Raise=True)
|
||||||
return
|
|
||||||
s = self.db[channel, id]
|
s = self.db[channel, id]
|
||||||
newS = changer(s)
|
newS = changer(s)
|
||||||
self.db[channel, id] = newS
|
self.db[channel, id] = newS
|
||||||
|
@ -133,8 +133,7 @@ class Lookup(callbacks.Privmsg):
|
|||||||
name = privmsgs.getArgs(args)
|
name = privmsgs.getArgs(args)
|
||||||
name = callbacks.canonicalName(name)
|
name = callbacks.canonicalName(name)
|
||||||
if name not in self.lookupDomains:
|
if name not in self.lookupDomains:
|
||||||
irc.error('That\'s not a valid lookup to remove.')
|
irc.errorInvalid('lookup', name, Raise=True)
|
||||||
return
|
|
||||||
db = self.dbHandler.getDb()
|
db = self.dbHandler.getDb()
|
||||||
cursor = db.cursor()
|
cursor = db.cursor()
|
||||||
try:
|
try:
|
||||||
@ -249,9 +248,7 @@ class Lookup(callbacks.Privmsg):
|
|||||||
try:
|
try:
|
||||||
r = utils.perlReToPythonRe(arg)
|
r = utils.perlReToPythonRe(arg)
|
||||||
except ValueError, e:
|
except ValueError, e:
|
||||||
irc.error('%r is not a valid regular expression' %
|
irc.errorInvalid('regular expression', arg, Raise=True)
|
||||||
arg)
|
|
||||||
return
|
|
||||||
def p(s, r=r):
|
def p(s, r=r):
|
||||||
return int(bool(r.search(s)))
|
return int(bool(r.search(s)))
|
||||||
db.create_function(predicateName, 1, p)
|
db.create_function(predicateName, 1, p)
|
||||||
|
@ -194,7 +194,7 @@ class Observer(callbacks.Privmsg):
|
|||||||
"""
|
"""
|
||||||
name = privmsgs.getArgs(args)
|
name = privmsgs.getArgs(args)
|
||||||
if name not in self.registryValue('observers'):
|
if name not in self.registryValue('observers'):
|
||||||
irc.error('That\'s not a valid observer.', Raise=True)
|
irc.errorInvalid('observer', name, Raise=True)
|
||||||
g = self.registryValue('observers.%s' % name, value=False)
|
g = self.registryValue('observers.%s' % name, value=False)
|
||||||
regexp = g()
|
regexp = g()
|
||||||
command = g.command()
|
command = g.command()
|
||||||
@ -222,8 +222,9 @@ class Observer(callbacks.Privmsg):
|
|||||||
probability = 1.0
|
probability = 1.0
|
||||||
(name, regexp, command) = privmsgs.getArgs(args, required=3)
|
(name, regexp, command) = privmsgs.getArgs(args, required=3)
|
||||||
if not registry.isValidRegistryName(name):
|
if not registry.isValidRegistryName(name):
|
||||||
irc.error('That\'s not a valid observer name. Please be sure '
|
irc.errorInvalid('observer name', name,
|
||||||
'there are no spaces in the name.', Raise=True)
|
'Please be sure there are no spaces in the name.',
|
||||||
|
Raise=True)
|
||||||
registerObserver(name, regexp, command, probability)
|
registerObserver(name, regexp, command, probability)
|
||||||
irc.replySuccess()
|
irc.replySuccess()
|
||||||
|
|
||||||
|
@ -323,8 +323,7 @@ class Quotes(callbacks.Privmsg):
|
|||||||
try:
|
try:
|
||||||
id = int(id)
|
id = int(id)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
irc.error('Invalid id: %r' % id)
|
irc.errorInvalid('id', id, Raise=True)
|
||||||
return
|
|
||||||
try:
|
try:
|
||||||
quote = self.db.get(channel, id)
|
quote = self.db.get(channel, id)
|
||||||
irc.reply(str(quote))
|
irc.reply(str(quote))
|
||||||
@ -342,7 +341,7 @@ class Quotes(callbacks.Privmsg):
|
|||||||
try:
|
try:
|
||||||
id = int(id)
|
id = int(id)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
irc.error('That\'s not a valid id: %r' % id)
|
irc.errorInvalid('id', id, Raise=True)
|
||||||
try:
|
try:
|
||||||
self.db.remove(channel, id)
|
self.db.remove(channel, id)
|
||||||
irc.replySuccess()
|
irc.replySuccess()
|
||||||
|
@ -112,9 +112,7 @@ class Todo(callbacks.Privmsg):
|
|||||||
try:
|
try:
|
||||||
userid = ircdb.users.getUserId(arg)
|
userid = ircdb.users.getUserId(arg)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
irc.error(
|
irc.errorInvalid('task or username', arg, Raise=True)
|
||||||
'%r is not a valid task id or username' % arg)
|
|
||||||
return
|
|
||||||
db = self.dbHandler.getDb()
|
db = self.dbHandler.getDb()
|
||||||
cursor = db.cursor()
|
cursor = db.cursor()
|
||||||
if not userid and not taskid:
|
if not userid and not taskid:
|
||||||
@ -151,8 +149,7 @@ class Todo(callbacks.Privmsg):
|
|||||||
cursor.execute("""SELECT userid,priority,added_at,task,active
|
cursor.execute("""SELECT userid,priority,added_at,task,active
|
||||||
FROM todo WHERE id = %s""", taskid)
|
FROM todo WHERE id = %s""", taskid)
|
||||||
if cursor.rowcount == 0:
|
if cursor.rowcount == 0:
|
||||||
irc.error('%r is not a valid task id' % taskid)
|
irc.errorInvalid('task id', taskid, Raise=True)
|
||||||
return
|
|
||||||
(userid, pri, added_at, task, active) = cursor.fetchone()
|
(userid, pri, added_at, task, active) = cursor.fetchone()
|
||||||
# Construct and return the reply
|
# Construct and return the reply
|
||||||
user = ircdb.users.getUser(userid)
|
user = ircdb.users.getUser(userid)
|
||||||
@ -191,8 +188,7 @@ class Todo(callbacks.Privmsg):
|
|||||||
try:
|
try:
|
||||||
priority = int(arg)
|
priority = int(arg)
|
||||||
except ValueError, e:
|
except ValueError, e:
|
||||||
irc.error('%r is an invalid priority' % arg)
|
irc.errorInvalid('priority', arg, Raise=True)
|
||||||
return
|
|
||||||
text = privmsgs.getArgs(rest)
|
text = privmsgs.getArgs(rest)
|
||||||
db = self.dbHandler.getDb()
|
db = self.dbHandler.getDb()
|
||||||
cursor = db.cursor()
|
cursor = db.cursor()
|
||||||
@ -272,9 +268,7 @@ class Todo(callbacks.Privmsg):
|
|||||||
try:
|
try:
|
||||||
r = utils.perlReToPythonRe(arg)
|
r = utils.perlReToPythonRe(arg)
|
||||||
except ValueError, e:
|
except ValueError, e:
|
||||||
irc.error('%r is not a valid regular expression' %
|
irc.errorInvalid('regular expression', arg, Raise=True)
|
||||||
arg)
|
|
||||||
return
|
|
||||||
def p(s, r=r):
|
def p(s, r=r):
|
||||||
return int(bool(r.search(s)))
|
return int(bool(r.search(s)))
|
||||||
db.create_function(predicateName, 1, p)
|
db.create_function(predicateName, 1, p)
|
||||||
@ -337,19 +331,17 @@ class Todo(callbacks.Privmsg):
|
|||||||
try:
|
try:
|
||||||
replacer = utils.perlReToReplacer(regexp)
|
replacer = utils.perlReToReplacer(regexp)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
irc.error('%r is not a valid regexp' % regexp)
|
irc.errorInvalid('regular expression', regexp, Raise=True)
|
||||||
return
|
|
||||||
db = self.dbHandler.getDb()
|
db = self.dbHandler.getDb()
|
||||||
cursor = db.cursor()
|
cursor = db.cursor()
|
||||||
cursor.execute("""SELECT task FROM todo
|
cursor.execute("""SELECT task FROM todo
|
||||||
WHERE userid = %s AND id = %s
|
WHERE userid = %s AND id = %s
|
||||||
AND active = 1""", userid, taskid)
|
AND active = 1""", userid, taskid)
|
||||||
if cursor.rowcount == 0:
|
if cursor.rowcount == 0:
|
||||||
irc.error('%r is not a valid task id' % taskid)
|
irc.errorInvalid('task id', taskid, Raise=True)
|
||||||
return
|
|
||||||
newtext = replacer(cursor.fetchone()[0])
|
newtext = replacer(cursor.fetchone()[0])
|
||||||
cursor.execute("""UPDATE todo SET task = %s
|
cursor.execute("""UPDATE todo SET task = %s WHERE id = %s""",
|
||||||
WHERE id = %s""", newtext, taskid)
|
newtext, taskid)
|
||||||
db.commit()
|
db.commit()
|
||||||
irc.replySuccess()
|
irc.replySuccess()
|
||||||
|
|
||||||
|
@ -166,7 +166,7 @@ class Topic(callbacks.Privmsg):
|
|||||||
n += len(topics)
|
n += len(topics)
|
||||||
return n
|
return n
|
||||||
except (ValueError, IndexError):
|
except (ValueError, IndexError):
|
||||||
irc.error('That\'s not a valid topic number.', Raise=True)
|
irc.errorInvalid('topic number', n, Raise=True)
|
||||||
|
|
||||||
def topic(self, irc, msg, args, channel):
|
def topic(self, irc, msg, args, channel):
|
||||||
"""[<channel>]
|
"""[<channel>]
|
||||||
@ -308,14 +308,12 @@ class Topic(callbacks.Privmsg):
|
|||||||
(number, regexp) = privmsgs.getArgs(args, required=2)
|
(number, regexp) = privmsgs.getArgs(args, required=2)
|
||||||
topics = self._splitTopic(irc.state.getTopic(channel), channel)
|
topics = self._splitTopic(irc.state.getTopic(channel), channel)
|
||||||
if not topics:
|
if not topics:
|
||||||
irc.error('There are no topics to change.')
|
irc.error('There are no topics to change.', Raise=True)
|
||||||
return
|
|
||||||
number = self._topicNumber(irc, number, topics=topics)
|
number = self._topicNumber(irc, number, topics=topics)
|
||||||
try:
|
try:
|
||||||
replacer = utils.perlReToReplacer(regexp)
|
replacer = utils.perlReToReplacer(regexp)
|
||||||
except ValueError, e:
|
except ValueError, e:
|
||||||
irc.error('The regexp wasn\'t valid: %s' % e)
|
irc.errorInvalid('regexp', regexp, Raise=True)
|
||||||
return
|
|
||||||
topics[number] = replacer(topics[number])
|
topics[number] = replacer(topics[number])
|
||||||
self._sendTopics(irc, channel, topics)
|
self._sendTopics(irc, channel, topics)
|
||||||
change = privmsgs.channel(change)
|
change = privmsgs.channel(change)
|
||||||
|
@ -303,10 +303,10 @@ class Words(callbacks.Privmsg):
|
|||||||
else:
|
else:
|
||||||
# User input an invalid character
|
# User input an invalid character
|
||||||
if len(letter) == 1:
|
if len(letter) == 1:
|
||||||
irc.error('That is not a valid letter.')
|
irc.errorInvalid('letter', letter, Raise=True)
|
||||||
# User input an invalid word (len(try) != len(hidden))
|
# User input an invalid word (len(try) != len(hidden))
|
||||||
else:
|
else:
|
||||||
irc.error('That is not a valid word guess.')
|
irc.errorInvalid('word guess', letter, Raise=True)
|
||||||
# Verify if the user won or lost
|
# Verify if the user won or lost
|
||||||
if game.guessed and game.tries > 0:
|
if game.guessed and game.tries > 0:
|
||||||
self._hangmanReply(irc, channel,
|
self._hangmanReply(irc, channel,
|
||||||
|
Loading…
Reference in New Issue
Block a user