mirror of
https://github.com/Mikaela/Limnoria.git
synced 2025-01-24 02:54:05 +01:00
Merge branch 'testing' of github.com:ProgVal/Limnoria into testing
This commit is contained in:
commit
18bafc725f
@ -41,10 +41,6 @@ def configure(advanced):
|
|||||||
from supybot.questions import expect, anything, something, yn
|
from supybot.questions import expect, anything, something, yn
|
||||||
conf.registerPlugin('Admin', True)
|
conf.registerPlugin('Admin', True)
|
||||||
|
|
||||||
|
|
||||||
Admin = conf.registerPlugin('Admin')
|
Admin = conf.registerPlugin('Admin')
|
||||||
# This is where your configuration variables (if any) should go. For example:
|
|
||||||
# conf.registerGlobalValue(Admin, 'someConfigVariableName',
|
|
||||||
# registry.Boolean(False, """Help for someConfigVariableName."""))
|
|
||||||
|
|
||||||
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
||||||
|
@ -231,34 +231,6 @@ class Admin(callbacks.Plugin):
|
|||||||
irc.reply(irc.nick)
|
irc.reply(irc.nick)
|
||||||
nick = wrap(nick, [additional('nick'), additional('something')])
|
nick = wrap(nick, [additional('nick'), additional('something')])
|
||||||
|
|
||||||
@internationalizeDocstring
|
|
||||||
def part(self, irc, msg, args, channel, reason):
|
|
||||||
"""[<channel>] [<reason>]
|
|
||||||
|
|
||||||
Tells the bot to part the list of channels you give it. <channel> is
|
|
||||||
only necessary if you want the bot to part a channel other than the
|
|
||||||
current channel. If <reason> is specified, use it as the part
|
|
||||||
message.
|
|
||||||
"""
|
|
||||||
if channel is None:
|
|
||||||
if irc.isChannel(msg.args[0]):
|
|
||||||
channel = msg.args[0]
|
|
||||||
else:
|
|
||||||
irc.error(Raise=True)
|
|
||||||
try:
|
|
||||||
network = conf.supybot.networks.get(irc.network)
|
|
||||||
network.channels().remove(channel)
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
if channel not in irc.state.channels:
|
|
||||||
irc.error(_('I\'m not in %s.') % channel, Raise=True)
|
|
||||||
irc.queueMsg(ircmsgs.part(channel, reason or msg.nick))
|
|
||||||
if msg.nick in irc.state.channels[channel].users:
|
|
||||||
irc.noReply()
|
|
||||||
else:
|
|
||||||
irc.replySuccess()
|
|
||||||
part = wrap(part, [optional('validChannel'), additional('text')])
|
|
||||||
|
|
||||||
class capability(callbacks.Commands):
|
class capability(callbacks.Commands):
|
||||||
|
|
||||||
@internationalizeDocstring
|
@internationalizeDocstring
|
||||||
|
@ -94,27 +94,6 @@ class AdminTestCase(PluginTestCase):
|
|||||||
self.assertEqual(m.args[0], '#foo')
|
self.assertEqual(m.args[0], '#foo')
|
||||||
self.assertEqual(m.args[1], 'key')
|
self.assertEqual(m.args[1], 'key')
|
||||||
|
|
||||||
def testPart(self):
|
|
||||||
def getAfterJoinMessages():
|
|
||||||
m = self.irc.takeMsg()
|
|
||||||
self.assertEqual(m.command, 'MODE')
|
|
||||||
m = self.irc.takeMsg()
|
|
||||||
self.assertEqual(m.command, 'MODE')
|
|
||||||
m = self.irc.takeMsg()
|
|
||||||
self.assertEqual(m.command, 'WHO')
|
|
||||||
self.assertError('part #foo')
|
|
||||||
self.assertRegexp('part #foo', 'not in')
|
|
||||||
self.irc.feedMsg(ircmsgs.join('#foo', prefix=self.prefix))
|
|
||||||
getAfterJoinMessages()
|
|
||||||
m = self.getMsg('part #foo')
|
|
||||||
self.assertEqual(m.command, 'PART')
|
|
||||||
self.irc.feedMsg(ircmsgs.join('#foo', prefix=self.prefix))
|
|
||||||
getAfterJoinMessages()
|
|
||||||
m = self.getMsg('part #foo reason')
|
|
||||||
self.assertEqual(m.command, 'PART')
|
|
||||||
self.assertEqual(m.args[0], '#foo')
|
|
||||||
self.assertEqual(m.args[1], 'reason')
|
|
||||||
|
|
||||||
def testNick(self):
|
def testNick(self):
|
||||||
original = conf.supybot.nick()
|
original = conf.supybot.nick()
|
||||||
try:
|
try:
|
||||||
|
@ -51,6 +51,15 @@ conf.registerChannelValue(Channel, 'nicksInPrivate',
|
|||||||
registry.Boolean(True, _("""Determines whether the output of 'nicks' will
|
registry.Boolean(True, _("""Determines whether the output of 'nicks' will
|
||||||
be sent in private. This prevents mass-highlights of a channel's users,
|
be sent in private. This prevents mass-highlights of a channel's users,
|
||||||
accidental or on purpose.""")))
|
accidental or on purpose.""")))
|
||||||
|
conf.registerChannelValue(Channel, 'rejoinDelay',
|
||||||
|
registry.NonNegativeInteger(0, _("""Determines how many seconds the bot will wait
|
||||||
|
before rejoining a channel if kicked and
|
||||||
|
supybot.plugins.Channel.alwaysRejoin is on.""")))
|
||||||
|
conf.registerChannelValue(Channel, 'partMsg',
|
||||||
|
registry.String('$version', _("""Determines what part message should be
|
||||||
|
used by default. If the part command is called without a part message,
|
||||||
|
this will be used. If this value is empty, then no part message will
|
||||||
|
be used (they are optional in the IRC protocol). The standard
|
||||||
|
substitutions ($version, $nick, etc.) are all handled appropriately.""")))
|
||||||
|
|
||||||
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
import sys
|
import sys
|
||||||
import fnmatch
|
import fnmatch
|
||||||
|
import time
|
||||||
|
|
||||||
import supybot.conf as conf
|
import supybot.conf as conf
|
||||||
import supybot.ircdb as ircdb
|
import supybot.ircdb as ircdb
|
||||||
@ -46,6 +47,7 @@ class Channel(callbacks.Plugin):
|
|||||||
"""This plugin provides various commands for channel management, such
|
"""This plugin provides various commands for channel management, such
|
||||||
as setting modes and channel-wide bans/ignores/capabilities. This is
|
as setting modes and channel-wide bans/ignores/capabilities. This is
|
||||||
a core Supybot plugin that should not be removed!"""
|
a core Supybot plugin that should not be removed!"""
|
||||||
|
|
||||||
def __init__(self, irc):
|
def __init__(self, irc):
|
||||||
self.__parent = super(Channel, self)
|
self.__parent = super(Channel, self)
|
||||||
self.__parent.__init__(irc)
|
self.__parent.__init__(irc)
|
||||||
@ -55,10 +57,18 @@ class Channel(callbacks.Plugin):
|
|||||||
channel = msg.args[0]
|
channel = msg.args[0]
|
||||||
if msg.args[1] == irc.nick:
|
if msg.args[1] == irc.nick:
|
||||||
if self.registryValue('alwaysRejoin', channel):
|
if self.registryValue('alwaysRejoin', channel):
|
||||||
self.log.info('Kicked from %s by %s. Rejoining.' %
|
delay = self.registryValue('rejoinDelay', channel)
|
||||||
(channel, msg.prefix))
|
|
||||||
networkGroup = conf.supybot.networks.get(irc.network)
|
networkGroup = conf.supybot.networks.get(irc.network)
|
||||||
irc.sendMsg(networkGroup.channels.join(channel))
|
if delay:
|
||||||
|
def f():
|
||||||
|
irc.sendMsg(networkGroup.channels.join(channel))
|
||||||
|
schedule.addEvent(f, time.time() + delay)
|
||||||
|
self.log.info('Kicked from %s by %s. Rejoining after %s '
|
||||||
|
'seconds.', channel, msg.prefix, delay)
|
||||||
|
else:
|
||||||
|
self.log.info('Kicked from %s by %s. Rejoining.',
|
||||||
|
channel, msg.prefix)
|
||||||
|
irc.sendMsg(networkGroup.channels.join(channel))
|
||||||
else:
|
else:
|
||||||
self.log.info('Kicked from %s by %s. Not auto-rejoining.' %
|
self.log.info('Kicked from %s by %s. Not auto-rejoining.' %
|
||||||
(channel, msg.prefix))
|
(channel, msg.prefix))
|
||||||
@ -258,17 +268,22 @@ class Channel(callbacks.Plugin):
|
|||||||
any('nickInChannel')])
|
any('nickInChannel')])
|
||||||
|
|
||||||
@internationalizeDocstring
|
@internationalizeDocstring
|
||||||
def cycle(self, irc, msg, args, channel):
|
def cycle(self, irc, msg, args, channel, reason):
|
||||||
"""[<channel>]
|
"""[<channel>]
|
||||||
|
|
||||||
If you have the #channel,op capability, this will cause the bot to
|
If you have the #channel,op capability, this will cause the bot to
|
||||||
"cycle", or PART and then JOIN the channel. <channel> is only necessary
|
"cycle", or PART and then JOIN the channel. <channel> is only necessary
|
||||||
if the message isn't sent in the channel itself.
|
if the message isn't sent in the channel itself. If <reason> is not
|
||||||
|
specified, the default part message specified in
|
||||||
|
supybot.plugins.Channel.partMsg will be used. No part message will be
|
||||||
|
used if neither a cycle reason nor a default part message is given.
|
||||||
"""
|
"""
|
||||||
self._sendMsg(irc, ircmsgs.part(channel, msg.nick))
|
reason = (reason or self.registryValue("partMsg", channel))
|
||||||
|
reason = ircutils.standardSubstitute(irc, msg, reason)
|
||||||
|
self._sendMsg(irc, ircmsgs.part(channel, reason))
|
||||||
networkGroup = conf.supybot.networks.get(irc.network)
|
networkGroup = conf.supybot.networks.get(irc.network)
|
||||||
self._sendMsg(irc, networkGroup.channels.join(channel))
|
self._sendMsg(irc, networkGroup.channels.join(channel))
|
||||||
cycle = wrap(cycle, ['op'])
|
cycle = wrap(cycle, ['op', additional('text')])
|
||||||
|
|
||||||
@internationalizeDocstring
|
@internationalizeDocstring
|
||||||
def kick(self, irc, msg, args, channel, nicks, reason):
|
def kick(self, irc, msg, args, channel, nicks, reason):
|
||||||
@ -941,6 +956,41 @@ class Channel(callbacks.Plugin):
|
|||||||
self.alertOps(irc, channel, text, frm=msg.nick)
|
self.alertOps(irc, channel, text, frm=msg.nick)
|
||||||
alert = wrap(alert, ['inChannel', 'text'])
|
alert = wrap(alert, ['inChannel', 'text'])
|
||||||
|
|
||||||
|
@internationalizeDocstring
|
||||||
|
def part(self, irc, msg, args, channel, reason):
|
||||||
|
"""[<channel>] [<reason>]
|
||||||
|
|
||||||
|
Tells the bot to part the list of channels you give it. <channel> is
|
||||||
|
only necessary if you want the bot to part a channel other than the
|
||||||
|
current channel. If <reason> is specified, use it as the part
|
||||||
|
message. Otherwise, the default part message specified in
|
||||||
|
supybot.plugins.Channel.partMsg will be used. No part message will be
|
||||||
|
used if no default is configured.
|
||||||
|
"""
|
||||||
|
if channel is None:
|
||||||
|
if irc.isChannel(msg.args[0]):
|
||||||
|
channel = msg.args[0]
|
||||||
|
else:
|
||||||
|
irc.error(Raise=True)
|
||||||
|
capability = ircdb.makeChannelCapability(channel, 'op')
|
||||||
|
hostmask = irc.state.nickToHostmask(msg.nick)
|
||||||
|
if not ircdb.checkCapability(hostmask, capability):
|
||||||
|
irc.errorNoCapability(capability, Raise=True)
|
||||||
|
try:
|
||||||
|
network = conf.supybot.networks.get(irc.network)
|
||||||
|
network.channels().remove(channel)
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
if channel not in irc.state.channels:
|
||||||
|
irc.error(_('I\'m not in %s.') % channel, Raise=True)
|
||||||
|
reason = (reason or self.registryValue("partMsg", channel))
|
||||||
|
reason = ircutils.standardSubstitute(irc, msg, reason)
|
||||||
|
irc.queueMsg(ircmsgs.part(channel, reason))
|
||||||
|
if msg.nick in irc.state.channels[channel].users:
|
||||||
|
irc.noReply()
|
||||||
|
else:
|
||||||
|
irc.replySuccess()
|
||||||
|
part = wrap(part, [optional('validChannel'), additional('text')])
|
||||||
|
|
||||||
Class = Channel
|
Class = Channel
|
||||||
|
|
||||||
|
@ -251,6 +251,27 @@ class ChannelTestCase(ChannelPluginTestCase):
|
|||||||
def testNicks(self):
|
def testNicks(self):
|
||||||
self.assertResponse('channel nicks', 'bar, foo, and test')
|
self.assertResponse('channel nicks', 'bar, foo, and test')
|
||||||
self.assertResponse('channel nicks --count', '3')
|
self.assertResponse('channel nicks --count', '3')
|
||||||
|
|
||||||
|
def testPart(self):
|
||||||
|
def getAfterJoinMessages():
|
||||||
|
m = self.irc.takeMsg()
|
||||||
|
self.assertEqual(m.command, 'MODE')
|
||||||
|
m = self.irc.takeMsg()
|
||||||
|
self.assertEqual(m.command, 'MODE')
|
||||||
|
m = self.irc.takeMsg()
|
||||||
|
self.assertEqual(m.command, 'WHO')
|
||||||
|
self.assertError('part #foo')
|
||||||
|
self.assertRegexp('part #foo', 'not in')
|
||||||
|
self.irc.feedMsg(ircmsgs.join('#foo', prefix=self.prefix))
|
||||||
|
getAfterJoinMessages()
|
||||||
|
m = self.getMsg('part #foo')
|
||||||
|
self.assertEqual(m.command, 'PART')
|
||||||
|
self.irc.feedMsg(ircmsgs.join('#foo', prefix=self.prefix))
|
||||||
|
getAfterJoinMessages()
|
||||||
|
m = self.getMsg('part #foo reason')
|
||||||
|
self.assertEqual(m.command, 'PART')
|
||||||
|
self.assertEqual(m.args[0], '#foo')
|
||||||
|
self.assertEqual(m.args[1], 'reason')
|
||||||
|
|
||||||
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ class Connection:
|
|||||||
capstr, msgid = re.search('<(.*)> (<.*>)$', string).groups()
|
capstr, msgid = re.search('<(.*)> (<.*>)$', string).groups()
|
||||||
self.capabilities = capstr.split('.')
|
self.capabilities = capstr.split('.')
|
||||||
self.messageid = msgid
|
self.messageid = msgid
|
||||||
|
|
||||||
def getcapabilities(self):
|
def getcapabilities(self):
|
||||||
"""Returns a list of the capabilities advertised by the server."""
|
"""Returns a list of the capabilities advertised by the server."""
|
||||||
return self.capabilities
|
return self.capabilities
|
||||||
@ -126,7 +126,7 @@ class Connection:
|
|||||||
network traffic!"""
|
network traffic!"""
|
||||||
if hasattr(self, 'dbdescs'):
|
if hasattr(self, 'dbdescs'):
|
||||||
return self.dbdescs
|
return self.dbdescs
|
||||||
|
|
||||||
self.sendcommand("SHOW DB")
|
self.sendcommand("SHOW DB")
|
||||||
self.dbdescs = self.get100dict()
|
self.dbdescs = self.get100dict()
|
||||||
return self.dbdescs
|
return self.dbdescs
|
||||||
@ -165,7 +165,7 @@ class Connection:
|
|||||||
def sendcommand(self, command):
|
def sendcommand(self, command):
|
||||||
"""Takes a command, without a newline character, and sends it to
|
"""Takes a command, without a newline character, and sends it to
|
||||||
the server."""
|
the server."""
|
||||||
self.wfile.write(command.encode('ascii') + b"\n")
|
self.wfile.write(command.encode('utf-8') + b"\n")
|
||||||
|
|
||||||
def define(self, database, word):
|
def define(self, database, word):
|
||||||
"""Returns a list of Definition objects for each matching
|
"""Returns a list of Definition objects for each matching
|
||||||
@ -182,7 +182,7 @@ class Connection:
|
|||||||
if database != '*' and database != '!' and \
|
if database != '*' and database != '!' and \
|
||||||
not database in self.getdbdescs():
|
not database in self.getdbdescs():
|
||||||
raise Exception("Invalid database '%s' specified" % database)
|
raise Exception("Invalid database '%s' specified" % database)
|
||||||
|
|
||||||
self.sendcommand("DEFINE " + enquote(database) + " " + enquote(word))
|
self.sendcommand("DEFINE " + enquote(database) + " " + enquote(word))
|
||||||
code = self.getresultcode()[0]
|
code = self.getresultcode()[0]
|
||||||
|
|
||||||
@ -249,11 +249,11 @@ class Database:
|
|||||||
a database name."""
|
a database name."""
|
||||||
self.conn = dictconn
|
self.conn = dictconn
|
||||||
self.name = dbname
|
self.name = dbname
|
||||||
|
|
||||||
def getname(self):
|
def getname(self):
|
||||||
"""Returns the short name for this database."""
|
"""Returns the short name for this database."""
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
def getdescription(self):
|
def getdescription(self):
|
||||||
if hasattr(self, 'description'):
|
if hasattr(self, 'description'):
|
||||||
return self.description
|
return self.description
|
||||||
@ -264,7 +264,7 @@ class Database:
|
|||||||
else:
|
else:
|
||||||
self.description = self.conn.getdbdescs()[self.getname()]
|
self.description = self.conn.getdbdescs()[self.getname()]
|
||||||
return self.description
|
return self.description
|
||||||
|
|
||||||
def getinfo(self):
|
def getinfo(self):
|
||||||
"""Returns a string of info describing this database."""
|
"""Returns a string of info describing this database."""
|
||||||
if hasattr(self, 'info'):
|
if hasattr(self, 'info'):
|
||||||
|
@ -243,8 +243,7 @@ class Network(callbacks.Plugin):
|
|||||||
L.append(format(_('is on %L'), normal))
|
L.append(format(_('is on %L'), normal))
|
||||||
else:
|
else:
|
||||||
if command == 'whois':
|
if command == 'whois':
|
||||||
L = [_('isn\'t on any non-secret channels or is using a '
|
L = [_('isn\'t on any publicly visible channels')]
|
||||||
'channel-list hiding umode.')]
|
|
||||||
else:
|
else:
|
||||||
L = []
|
L = []
|
||||||
channels = format('%L', L)
|
channels = format('%L', L)
|
||||||
|
@ -46,10 +46,11 @@ conf.registerGlobalValue(Owner, 'public',
|
|||||||
registry.Boolean(True, """Determines whether this plugin is publicly
|
registry.Boolean(True, """Determines whether this plugin is publicly
|
||||||
visible."""))
|
visible."""))
|
||||||
conf.registerGlobalValue(Owner, 'quitMsg',
|
conf.registerGlobalValue(Owner, 'quitMsg',
|
||||||
registry.String('', """Determines what quit message will be used by default.
|
registry.String('$version', """Determines what quit message will be used by default.
|
||||||
If the quit command is called without a quit message, this will be used. If
|
If the quit command is called without a quit message, this will be used. If
|
||||||
this value is empty, the nick of the person giving the quit command will be
|
this value is empty, the nick of the person giving the quit command will be
|
||||||
used."""))
|
used. The standard substitutions ($version, $nick, etc.) are all handled
|
||||||
|
appropriately."""))
|
||||||
|
|
||||||
conf.registerGroup(conf.supybot.commands, 'renames', orderAlphabetically=True)
|
conf.registerGroup(conf.supybot.commands, 'renames', orderAlphabetically=True)
|
||||||
|
|
||||||
|
@ -344,9 +344,11 @@ class Owner(callbacks.Plugin):
|
|||||||
|
|
||||||
Exits the bot with the QUIT message <text>. If <text> is not given,
|
Exits the bot with the QUIT message <text>. If <text> is not given,
|
||||||
the default quit message (supybot.plugins.Owner.quitMsg) will be used.
|
the default quit message (supybot.plugins.Owner.quitMsg) will be used.
|
||||||
If there is no default quitMsg set, your nick will be used.
|
If there is no default quitMsg set, your nick will be used. The standard
|
||||||
|
substitutions ($version, $nick, etc.) are all handled appropriately.
|
||||||
"""
|
"""
|
||||||
text = text or self.registryValue('quitMsg') or msg.nick
|
text = text or self.registryValue('quitMsg') or msg.nick
|
||||||
|
text = ircutils.standardSubstitute(irc, msg, text)
|
||||||
irc.noReply()
|
irc.noReply()
|
||||||
m = ircmsgs.quit(text)
|
m = ircmsgs.quit(text)
|
||||||
world.upkeep()
|
world.upkeep()
|
||||||
|
@ -61,8 +61,11 @@ class QuoteGrabsRecord(dbi.Record):
|
|||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
grabber = plugins.getUserName(self.grabber)
|
grabber = plugins.getUserName(self.grabber)
|
||||||
return format(_('%s (Said by: %s; grabbed by %s at %t)'),
|
if self.at:
|
||||||
self.text, self.hostmask, grabber, self.at)
|
return format(_('%s (Said by: %s; grabbed by %s at %t)'),
|
||||||
|
self.text, self.hostmask, grabber, self.at)
|
||||||
|
else:
|
||||||
|
return format('%s', self.text)
|
||||||
|
|
||||||
class SqliteQuoteGrabsDB(object):
|
class SqliteQuoteGrabsDB(object):
|
||||||
def __init__(self, filename):
|
def __init__(self, filename):
|
||||||
@ -105,7 +108,7 @@ class SqliteQuoteGrabsDB(object):
|
|||||||
db.commit()
|
db.commit()
|
||||||
return db
|
return db
|
||||||
|
|
||||||
def get(self, channel, id):
|
def get(self, channel, id, quoteonly = 0):
|
||||||
db = self._getDb(channel)
|
db = self._getDb(channel)
|
||||||
cursor = db.cursor()
|
cursor = db.cursor()
|
||||||
cursor.execute("""SELECT id, nick, quote, hostmask, added_at, added_by
|
cursor.execute("""SELECT id, nick, quote, hostmask, added_at, added_by
|
||||||
@ -114,8 +117,11 @@ class SqliteQuoteGrabsDB(object):
|
|||||||
if len(results) == 0:
|
if len(results) == 0:
|
||||||
raise dbi.NoRecordError
|
raise dbi.NoRecordError
|
||||||
(id, by, quote, hostmask, at, grabber) = results[0]
|
(id, by, quote, hostmask, at, grabber) = results[0]
|
||||||
return QuoteGrabsRecord(id, by=by, text=quote, hostmask=hostmask,
|
if quoteonly is 0:
|
||||||
at=int(at), grabber=grabber)
|
return QuoteGrabsRecord(id, by=by, text=quote, hostmask=hostmask,
|
||||||
|
at=int(at), grabber=grabber)
|
||||||
|
else:
|
||||||
|
return QuoteGrabsRecord(id, text=quote)
|
||||||
|
|
||||||
def random(self, channel, nick):
|
def random(self, channel, nick):
|
||||||
db = self._getDb(channel)
|
db = self._getDb(channel)
|
||||||
@ -359,6 +365,20 @@ class QuoteGrabs(callbacks.Plugin):
|
|||||||
'grabbed quotes in the database?'))
|
'grabbed quotes in the database?'))
|
||||||
random = wrap(random, ['channeldb', additional('nick')])
|
random = wrap(random, ['channeldb', additional('nick')])
|
||||||
|
|
||||||
|
@internationalizeDocstring
|
||||||
|
def say(self, irc, msg, args, channel, id):
|
||||||
|
"""[<channel>] <id>
|
||||||
|
|
||||||
|
Return the quotegrab with the given <id>. <channel> is only necessary
|
||||||
|
if the message isn't sent in the channel itself.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
irc.reply(self.db.get(channel, id, 1))
|
||||||
|
except dbi.NoRecordError:
|
||||||
|
irc.error(_('No quotegrab for id %s') % utils.str.quoted(id),
|
||||||
|
Raise=True)
|
||||||
|
say = wrap(say, ['channeldb', 'id'])
|
||||||
|
|
||||||
@internationalizeDocstring
|
@internationalizeDocstring
|
||||||
def get(self, irc, msg, args, channel, id):
|
def get(self, irc, msg, args, channel, id):
|
||||||
"""[<channel>] <id>
|
"""[<channel>] <id>
|
||||||
|
@ -225,6 +225,17 @@ class Seen(callbacks.Plugin):
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
irc.reply(format(_('I have not seen %s.'), name))
|
irc.reply(format(_('I have not seen %s.'), name))
|
||||||
|
|
||||||
|
def _checkChannelPresence(self, irc, channel, target, you):
|
||||||
|
if channel not in irc.state.channels:
|
||||||
|
irc.error(_("I'm not in %s." % channel), Raise=True)
|
||||||
|
if target not in irc.state.channels[channel].users:
|
||||||
|
if you:
|
||||||
|
msg = format(_('You must be in %s to use this command.'), channel)
|
||||||
|
else:
|
||||||
|
msg = format(_('%s must be in %s to use this command.'),
|
||||||
|
target, channel)
|
||||||
|
irc.error(msg, Raise=True)
|
||||||
|
|
||||||
@internationalizeDocstring
|
@internationalizeDocstring
|
||||||
def seen(self, irc, msg, args, channel, name):
|
def seen(self, irc, msg, args, channel, name):
|
||||||
"""[<channel>] <nick>
|
"""[<channel>] <nick>
|
||||||
@ -236,9 +247,7 @@ class Seen(callbacks.Plugin):
|
|||||||
if name and ircutils.strEqual(name, irc.nick):
|
if name and ircutils.strEqual(name, irc.nick):
|
||||||
irc.reply(_("You've found me!"))
|
irc.reply(_("You've found me!"))
|
||||||
return
|
return
|
||||||
if msg.nick not in irc.state.channels[channel].users:
|
self._checkChannelPresence(irc, channel, msg.nick, True)
|
||||||
irc.error(format('You must be in %s to use this command.', channel))
|
|
||||||
return
|
|
||||||
self._seen(irc, channel, name)
|
self._seen(irc, channel, name)
|
||||||
seen = wrap(seen, ['channel', 'something'])
|
seen = wrap(seen, ['channel', 'something'])
|
||||||
|
|
||||||
@ -256,9 +265,7 @@ class Seen(callbacks.Plugin):
|
|||||||
if name and ircutils.strEqual(name, irc.nick):
|
if name and ircutils.strEqual(name, irc.nick):
|
||||||
irc.reply(_("You've found me!"))
|
irc.reply(_("You've found me!"))
|
||||||
return
|
return
|
||||||
if msg.nick not in irc.state.channels[channel].users:
|
self._checkChannelPresence(irc, channel, msg.nick, True)
|
||||||
irc.error(format('You must be in %s to use this command.', channel))
|
|
||||||
return
|
|
||||||
if name and optlist:
|
if name and optlist:
|
||||||
raise callbacks.ArgumentError
|
raise callbacks.ArgumentError
|
||||||
elif name:
|
elif name:
|
||||||
@ -295,9 +302,7 @@ class Seen(callbacks.Plugin):
|
|||||||
Returns the last thing said in <channel>. <channel> is only necessary
|
Returns the last thing said in <channel>. <channel> is only necessary
|
||||||
if the message isn't sent in the channel itself.
|
if the message isn't sent in the channel itself.
|
||||||
"""
|
"""
|
||||||
if msg.nick not in irc.state.channels[channel].users:
|
self._checkChannelPresence(irc, channel, msg.nick, True)
|
||||||
irc.error(format('You must be in %s to use this command.', channel))
|
|
||||||
return
|
|
||||||
self._last(irc, channel)
|
self._last(irc, channel)
|
||||||
last = wrap(last, ['channel'])
|
last = wrap(last, ['channel'])
|
||||||
|
|
||||||
@ -327,9 +332,7 @@ class Seen(callbacks.Plugin):
|
|||||||
<channel> is only necessary if the message isn't sent in the channel
|
<channel> is only necessary if the message isn't sent in the channel
|
||||||
itself.
|
itself.
|
||||||
"""
|
"""
|
||||||
if msg.nick not in irc.state.channels[channel].users:
|
self._checkChannelPresence(irc, channel, msg.nick, True)
|
||||||
irc.error(format('You must be in %s to use this command.', channel))
|
|
||||||
return
|
|
||||||
self._user(irc, channel, user)
|
self._user(irc, channel, user)
|
||||||
user = wrap(user, ['channel', 'otherUser'])
|
user = wrap(user, ['channel', 'otherUser'])
|
||||||
|
|
||||||
@ -343,13 +346,10 @@ class Seen(callbacks.Plugin):
|
|||||||
"""
|
"""
|
||||||
if nick is None:
|
if nick is None:
|
||||||
nick = msg.nick
|
nick = msg.nick
|
||||||
if channel not in irc.state.channels:
|
you = True
|
||||||
irc.error(_('I am not in %s.') % channel)
|
else:
|
||||||
return
|
you = False
|
||||||
if nick not in irc.state.channels[channel].users:
|
self._checkChannelPresence(irc, channel, nick, you)
|
||||||
irc.error(format(_('%s must be in %s to use this command.'),
|
|
||||||
('You' if nick == msg.nick else nick), channel))
|
|
||||||
return
|
|
||||||
if nick is None:
|
if nick is None:
|
||||||
nick = msg.nick
|
nick = msg.nick
|
||||||
end = None # By default, up until the most recent message.
|
end = None # By default, up until the most recent message.
|
||||||
|
@ -42,8 +42,8 @@ def configure(advanced):
|
|||||||
conf.supybot.plugins.ShrinkUrl.shrinkSnarfer.setValue(True)
|
conf.supybot.plugins.ShrinkUrl.shrinkSnarfer.setValue(True)
|
||||||
|
|
||||||
class ShrinkService(registry.OnlySomeStrings):
|
class ShrinkService(registry.OnlySomeStrings):
|
||||||
"""Valid values include 'ln', 'tiny', 'goo', 'ur1', and 'x0'."""
|
"""Valid values include 'tiny', 'goo', 'ur1', and 'x0'."""
|
||||||
validStrings = ('ln', 'tiny', 'goo', 'ur1', 'x0')
|
validStrings = ('tiny', 'goo', 'ur1', 'x0')
|
||||||
|
|
||||||
class ShrinkCycle(registry.SpaceSeparatedListOfStrings):
|
class ShrinkCycle(registry.SpaceSeparatedListOfStrings):
|
||||||
"""Valid values include 'ln', 'tiny', 'goo', 'ur1', and 'x0'."""
|
"""Valid values include 'ln', 'tiny', 'goo', 'ur1', and 'x0'."""
|
||||||
@ -71,7 +71,7 @@ conf.registerChannelValue(ShrinkUrl, 'shrinkSnarfer',
|
|||||||
shrink snarfer is enabled. This snarfer will watch for URLs in the
|
shrink snarfer is enabled. This snarfer will watch for URLs in the
|
||||||
channel, and if they're sufficiently long (as determined by
|
channel, and if they're sufficiently long (as determined by
|
||||||
supybot.plugins.ShrinkUrl.minimumLength) it will post a
|
supybot.plugins.ShrinkUrl.minimumLength) it will post a
|
||||||
smaller URL from either ln-s.net or tinyurl.com, as denoted in
|
smaller URL from tinyurl.com, as denoted in
|
||||||
supybot.plugins.ShrinkUrl.default.""")))
|
supybot.plugins.ShrinkUrl.default.""")))
|
||||||
conf.registerChannelValue(ShrinkUrl.shrinkSnarfer, 'showDomain',
|
conf.registerChannelValue(ShrinkUrl.shrinkSnarfer, 'showDomain',
|
||||||
registry.Boolean(True, _("""Determines whether the snarfer will show the
|
registry.Boolean(True, _("""Determines whether the snarfer will show the
|
||||||
|
@ -171,37 +171,6 @@ class ShrinkUrl(callbacks.PluginRegexp):
|
|||||||
shrinkSnarfer = urlSnarfer(shrinkSnarfer)
|
shrinkSnarfer = urlSnarfer(shrinkSnarfer)
|
||||||
shrinkSnarfer.__doc__ = utils.web._httpUrlRe
|
shrinkSnarfer.__doc__ = utils.web._httpUrlRe
|
||||||
|
|
||||||
@retry
|
|
||||||
def _getLnUrl(self, url):
|
|
||||||
url = utils.web.urlquote(url)
|
|
||||||
try:
|
|
||||||
return self.db.get('ln', url)
|
|
||||||
except KeyError:
|
|
||||||
text = utils.web.getUrl('http://ln-s.net/home/api.jsp?url=' + url)
|
|
||||||
text = text.decode()
|
|
||||||
(code, text) = text.split(None, 1)
|
|
||||||
text = text.strip()
|
|
||||||
if code == '200':
|
|
||||||
self.db.set('ln', url, text)
|
|
||||||
return text
|
|
||||||
else:
|
|
||||||
raise ShrinkError(text)
|
|
||||||
|
|
||||||
@internationalizeDocstring
|
|
||||||
def ln(self, irc, msg, args, url):
|
|
||||||
"""<url>
|
|
||||||
|
|
||||||
Returns an ln-s.net version of <url>.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
lnurl = self._getLnUrl(url)
|
|
||||||
m = irc.reply(lnurl)
|
|
||||||
if m is not None:
|
|
||||||
m.tag('shrunken')
|
|
||||||
except ShrinkError as e:
|
|
||||||
irc.error(str(e))
|
|
||||||
ln = thread(wrap(ln, ['httpUrl']))
|
|
||||||
|
|
||||||
@retry
|
@retry
|
||||||
def _getTinyUrl(self, url):
|
def _getTinyUrl(self, url):
|
||||||
try:
|
try:
|
||||||
|
@ -39,8 +39,6 @@ class ShrinkUrlTestCase(ChannelPluginTestCase):
|
|||||||
'term=all+your+base+are+belong+to+us'
|
'term=all+your+base+are+belong+to+us'
|
||||||
tests = {'tiny': [(sfUrl, r'http://tinyurl.com/b7wyvfz'),
|
tests = {'tiny': [(sfUrl, r'http://tinyurl.com/b7wyvfz'),
|
||||||
(udUrl, r'http://tinyurl.com/u479')],
|
(udUrl, r'http://tinyurl.com/u479')],
|
||||||
'ln': [(sfUrl, r'http://ln-s.net/\+PE-'),
|
|
||||||
(udUrl, r'http://ln-s.net/2\$K')],
|
|
||||||
'goo': [(sfUrl, r'http://goo.gl/3c59N'),
|
'goo': [(sfUrl, r'http://goo.gl/3c59N'),
|
||||||
(udUrl, r'http://goo.gl/ocTga')],
|
(udUrl, r'http://goo.gl/ocTga')],
|
||||||
'ur1': [(sfUrl, r'http://ur1.ca/9xl25'),
|
'ur1': [(sfUrl, r'http://ur1.ca/9xl25'),
|
||||||
@ -62,16 +60,14 @@ class ShrinkUrlTestCase(ChannelPluginTestCase):
|
|||||||
origsnarfer = snarfer()
|
origsnarfer = snarfer()
|
||||||
try:
|
try:
|
||||||
self.assertNotError(
|
self.assertNotError(
|
||||||
'config plugins.ShrinkUrl.serviceRotation ln x0')
|
'config plugins.ShrinkUrl.serviceRotation goo x0')
|
||||||
self.assertError(
|
self.assertError(
|
||||||
'config plugins.ShrinkUrl.serviceRotation ln x1')
|
'config plugins.ShrinkUrl.serviceRotation goo x1')
|
||||||
snarfer.setValue(True)
|
snarfer.setValue(True)
|
||||||
self.assertSnarfRegexp(self.udUrl, r'.*%s.* \(at' %
|
self.assertSnarfRegexp(self.udUrl, r'.*%s.* \(at' %
|
||||||
self.tests['ln'][1][1])
|
self.tests['goo'][1][1])
|
||||||
self.assertSnarfRegexp(self.udUrl, r'.*%s.* \(at' %
|
self.assertSnarfRegexp(self.udUrl, r'.*%s.* \(at' %
|
||||||
self.tests['x0'][1][1])
|
self.tests['x0'][1][1])
|
||||||
self.assertSnarfRegexp(self.udUrl, r'.*%s.* \(at' %
|
|
||||||
self.tests['ln'][1][1])
|
|
||||||
finally:
|
finally:
|
||||||
cycle.setValue(origcycle)
|
cycle.setValue(origcycle)
|
||||||
snarfer.setValue(origsnarfer)
|
snarfer.setValue(origsnarfer)
|
||||||
@ -93,9 +89,6 @@ class ShrinkUrlTestCase(ChannelPluginTestCase):
|
|||||||
def testTinysnarf(self):
|
def testTinysnarf(self):
|
||||||
self._snarf('tiny')
|
self._snarf('tiny')
|
||||||
|
|
||||||
def testLnsnarf(self):
|
|
||||||
self._snarf('ln')
|
|
||||||
|
|
||||||
def testGoosnarf(self):
|
def testGoosnarf(self):
|
||||||
self._snarf('goo')
|
self._snarf('goo')
|
||||||
|
|
||||||
|
@ -69,6 +69,7 @@ import supybot.i18n as i18n
|
|||||||
import supybot.utils as utils
|
import supybot.utils as utils
|
||||||
import supybot.registry as registry
|
import supybot.registry as registry
|
||||||
import supybot.questions as questions
|
import supybot.questions as questions
|
||||||
|
import supybot.ircutils as ircutils
|
||||||
|
|
||||||
from supybot.version import version
|
from supybot.version import version
|
||||||
|
|
||||||
@ -104,6 +105,7 @@ def main():
|
|||||||
for irc in world.ircs:
|
for irc in world.ircs:
|
||||||
quitmsg = conf.supybot.plugins.Owner.quitMsg() or \
|
quitmsg = conf.supybot.plugins.Owner.quitMsg() or \
|
||||||
'Ctrl-C at console.'
|
'Ctrl-C at console.'
|
||||||
|
quitmsg = ircutils.standardSubstitute(irc, None, quitmsg)
|
||||||
irc.queueMsg(ircmsgs.quit(quitmsg))
|
irc.queueMsg(ircmsgs.quit(quitmsg))
|
||||||
irc.die()
|
irc.die()
|
||||||
except SystemExit as e:
|
except SystemExit as e:
|
||||||
|
@ -470,8 +470,7 @@ registerChannelValue(supybot.reply, 'withNotice',
|
|||||||
registerGlobalValue(supybot.reply, 'withNoticeWhenPrivate',
|
registerGlobalValue(supybot.reply, 'withNoticeWhenPrivate',
|
||||||
registry.Boolean(True, _("""Determines whether the bot will reply with a
|
registry.Boolean(True, _("""Determines whether the bot will reply with a
|
||||||
notice when it is sending a private message, in order not to open a /query
|
notice when it is sending a private message, in order not to open a /query
|
||||||
window in clients. This can be overridden by individual users via the user
|
window in clients.""")))
|
||||||
configuration variable reply.withNoticeWhenPrivate.""")))
|
|
||||||
|
|
||||||
registerChannelValue(supybot.reply, 'withNickPrefix',
|
registerChannelValue(supybot.reply, 'withNickPrefix',
|
||||||
registry.Boolean(True, _("""Determines whether the bot will always prefix
|
registry.Boolean(True, _("""Determines whether the bot will always prefix
|
||||||
|
@ -49,7 +49,7 @@ from cStringIO import StringIO as sio
|
|||||||
|
|
||||||
from . import utils
|
from . import utils
|
||||||
from . import minisix
|
from . import minisix
|
||||||
|
from .version import version
|
||||||
|
|
||||||
def debug(s, *args):
|
def debug(s, *args):
|
||||||
"""Prints a debug string. Most likely replaced by our logging debug."""
|
"""Prints a debug string. Most likely replaced by our logging debug."""
|
||||||
@ -690,6 +690,7 @@ def standardSubstitute(irc, msg, text, env=None):
|
|||||||
'm': localtime[4], 'min': localtime[4], 'minute': localtime[4],
|
'm': localtime[4], 'min': localtime[4], 'minute': localtime[4],
|
||||||
's': localtime[5], 'sec': localtime[5], 'second': localtime[5],
|
's': localtime[5], 'sec': localtime[5], 'second': localtime[5],
|
||||||
'tz': time.strftime('%Z', localtime),
|
'tz': time.strftime('%Z', localtime),
|
||||||
|
'version': 'Supybot %s' % version,
|
||||||
})
|
})
|
||||||
if irc:
|
if irc:
|
||||||
vars.update({
|
vars.update({
|
||||||
|
Loading…
Reference in New Issue
Block a user