Various improvements.

* Encyclopedia, PackageInfo:
  + Make repeat delay a setting.
  + Update default configuration.
* Bugtracker: Fix inconsistencies in network specificity.
This commit is contained in:
Krytarik Raido 2021-12-02 22:13:04 +01:00
parent df480587c9
commit e9306925c0
9 changed files with 106 additions and 70 deletions

View File

@ -23,7 +23,7 @@ import supybot
import supybot.world as world
from importlib import reload
__version__ = "4.9.0"
__version__ = "5.0.0"
__author__ = supybot.Author("Krytarik Raido", "krytarik", "krytarik@gmail.com")
__contributors__ = {
supybot.Author("Dennis Kaarsemaker", "Seveas", "dennis@kaarsemaker.net"): ['Original Author'],

View File

@ -54,6 +54,7 @@ def configure(advanced):
commitSnarfer = yn("Enable detecting commit hashes and URLs in all channels?", default=Bugtracker.commitSnarfer._default)
cveSnarfer = yn("Enable detecting CVE numbers and URLs in all channels?", default=Bugtracker.cveSnarfer._default)
oopsSnarfer = yn("Enable detecting Launchpad OOPS IDs in all channels?", default=Bugtracker.oopsSnarfer._default)
if advanced:
replyNoBugtracker = something("What should the bot reply with when a user requests information from an unknown bug tracker?", default=Bugtracker.replyNoBugtracker._default)
snarfTarget = something("What should be the default bug tracker used when none is specified?", default=Bugtracker.snarfTarget._default)

View File

@ -103,8 +103,8 @@ class Bugtracker(callbacks.PluginRegexp):
for k in list(self.shown.keys()):
if self.shown[k] < now - self.registryValue('repeatdelay', channel, network):
self.shown.pop(k)
if (channel, tracker, bugid) not in self.shown:
self.shown[(channel, tracker, bugid)] = now
if (network, channel, tracker, bugid) not in self.shown:
self.shown[(network, channel, tracker, bugid)] = now
return True
return False
@ -320,7 +320,7 @@ class Bugtracker(callbacks.PluginRegexp):
channel = msg.channel
if checkAddressed(msg.args[1].strip(), channel):
return
if not self.registryValue('{}Snarfer'.format(termtype), channel):
if not self.registryValue('{}Snarfer'.format(termtype), channel, irc.network):
return
nbugs = msg.tagged('nbugs') or 0
if nbugs >= 5:
@ -418,7 +418,7 @@ class Bugtracker(callbacks.PluginRegexp):
channel = msg.channel
if checkAddressed(msg.args[1].strip(), channel):
return
if not self.registryValue('{}Snarfer'.format(urltype), channel):
if not self.registryValue('{}Snarfer'.format(urltype), channel, irc.network):
return
nbugs = msg.tagged('nbugs') or 0
if nbugs >= 5:

View File

@ -24,7 +24,7 @@ import supybot
import supybot.world as world
from importlib import reload
__version__ = "4.1.1"
__version__ = "4.2.0"
__author__ = supybot.Author("Krytarik Raido", "krytarik", "krytarik@gmail.com")
__contributors__ = {
supybot.Author("Dennis Kaarsemaker", "Seveas", "dennis@kaarsemaker.net"): ['Original Author'],

View File

@ -29,7 +29,22 @@ def configure(advanced):
Encyclopedia = conf.registerPlugin('Encyclopedia', True)
def getRepeatdelay():
output("How many seconds should the bot wait before repeating factoids?")
repeatdelay = something("Enter a number greater or equal to 0.", default=Encyclopedia.repeatdelay._default)
try:
repeatdelay = int(repeatdelay)
if repeatdelay < 0:
raise TypeError
except TypeError:
output("Invalid value '%s', it must be an integer greater or equal to 0." % repeatdelay)
return getRepeatdelay()
else:
return repeatdelay
enabled = yn("Enable Encyclopedia for all channels?", default=Encyclopedia.enabled._default)
if advanced:
datadir = something("Which directory should the factoids database be in?", default=Encyclopedia.datadir._default)
database = something("What should be the name of the default database (without the .db extension)?", default=Encyclopedia.database._default)
@ -40,6 +55,7 @@ def configure(advanced):
ignores_i = anything("Which factoid requests should the bot always ignore?", default=', '.join(Encyclopedia.ignores._default))
for name in re.split(r'[,\s]+', ignores_i):
ignores.add(name.lower())
repeatdelay = getRepeatdelay()
curStable = something("What is short name of the current stable release?", default=Encyclopedia.curStable._default)
curStableLong = something("What is long name of the current stable release?", default=Encyclopedia.curStableLong._default)
@ -57,6 +73,7 @@ def configure(advanced):
database = Encyclopedia.database._default
prefixchar = Encyclopedia.prefixchar._default
ignores = Encyclopedia.ignores._default
repeatdelay = Encyclopedia.repeatdelay._default
curStable = Encyclopedia.curStable._default
curStableLong = Encyclopedia.curStableLong._default
curStableNum = Encyclopedia.curStableNum._default
@ -68,7 +85,7 @@ def configure(advanced):
curLTSNum = Encyclopedia.curLTSNum._default
relaychannel = anything("What channel/nick should the bot forward edit messages to?", default=Encyclopedia.relaychannel._default)
output("What message should the bot reply with when a factoid can not be found?")
output("What message should the bot reply with when a factoid cannot be found?")
notfoundmsg = something("If you include a '%s' in the message, it will be replaced with the requested factoid", default=Encyclopedia.notfoundmsg._default)
alert = set([])
output("When certain factoids are called an alert can be forwarded to a channel/nick")
@ -96,6 +113,7 @@ def configure(advanced):
Encyclopedia.relaychannel.setValue(relaychannel)
Encyclopedia.notfoundmsg.setValue(notfoundmsg)
Encyclopedia.alert.setValue(alert)
Encyclopedia.remotedb.setValue(remotedb)
Encyclopedia.privateNotFound.setValue(privateNotFound)
# Create the initial database
@ -189,6 +207,9 @@ conf.registerChannelValue(Encyclopedia, 'remotedb',
conf.registerChannelValue(Encyclopedia, 'ignores',
registry.SpaceSeparatedListOfStrings(['info', 'depends', 'find'], 'Factoid names to ignore', private=True))
conf.registerChannelValue(Encyclopedia, 'repeatdelay',
registry.Integer(60, "Number of seconds to wait between repeated factoid calls"))
conf.registerChannelValue(Encyclopedia, 'privateNotFound',
registry.Boolean(False, "Send notfoundmsg in private rather than in the channel"))
@ -197,22 +218,22 @@ conf.registerChannelValue(Encyclopedia, 'forcedFactoid',
conf.registerGlobalValue(Encyclopedia, 'curStable',
registry.String('Artful', "Current stable release"))
registry.String('Impish', "Current stable release"))
conf.registerGlobalValue(Encyclopedia, 'curStableLong',
registry.String('Artful Aardvark', "Current stable release"))
registry.String('Impish Indri', "Current stable release"))
conf.registerGlobalValue(Encyclopedia, 'curStableNum',
registry.String('17.10', "Current stable release"))
registry.String('21.10', "Current stable release"))
conf.registerGlobalValue(Encyclopedia, 'curDevel',
registry.String('Bionic', "Current development release"))
registry.String('Jammy', "Current development release"))
conf.registerGlobalValue(Encyclopedia, 'curDevelLong',
registry.String('Bionic Beaver', "Current development release"))
registry.String('Jammy Jellyfish', "Current development release"))
conf.registerGlobalValue(Encyclopedia, 'curDevelNum',
registry.String('18.04', "Current development release"))
registry.String('22.04', "Current development release"))
conf.registerGlobalValue(Encyclopedia, 'curLTS',
registry.String('Xenial', "Current LTS release"))
registry.String('Focal', "Current LTS release"))
conf.registerGlobalValue(Encyclopedia, 'curLTSLong',
registry.String('Xenial Xerus', "Current LTS release"))
registry.String('Focal Fossa', "Current LTS release"))
conf.registerGlobalValue(Encyclopedia, 'curLTSNum',
registry.String('16.04', "Current LTS release"))
registry.String('20.04', "Current LTS release"))

View File

@ -84,28 +84,6 @@ class FactoidSet:
self.global_primary = self.global_secondary = \
self.channel_primary = self.channel_secondary = None
# Repeat filtering message queue
msgcache = {}
def queue(irc, target, msg):
if world.testing:
# don't mess up testcases
irc.reply(msg, to=target, private=True)
return
now = time.time()
for m in list(msgcache.keys()):
if msgcache[m] < now - 30:
msgcache.pop(m)
for m in msgcache:
if m[0] == irc and m[1] == target:
oldmsg = m[2]
if oldmsg.endswith(msg):
break
if msg.endswith(oldmsg) and msg[:-len(oldmsg)].endswith(': '):
msg = msg[:-len(oldmsg)] + 'Please see above'
else:
msgcache[(irc, target, msg)] = now
irc.reply(msg, to=target, private=True)
def capab(prefix, capability):
# too bad people don't use supybot's own methods,
# it would save me the trouble of hacking this up
@ -172,6 +150,7 @@ class Encyclopedia(callbacks.Plugin):
self.databases = {}
self.times = {}
self.edits = {}
self.shown = {}
self.alert = False
self.defaultIrc = irc
@ -224,6 +203,26 @@ class Encyclopedia(callbacks.Plugin):
irc.reply(', '.join([u.name for u in list(ircdb.users.users.values()) if capab(u.name, 'addeditors')]), private=True)
moderators = wrap(moderators)
# Repeat filtering message queue
def queue(self, irc, target, msg):
if world.testing:
# don't mess up testcases
irc.reply(msg, to=target, private=True)
return
now = time.time()
for m in list(self.shown.keys()):
if self.shown[m] < now - self.registryValue('repeatdelay', target):
self.shown.pop(m)
for (net, tgt, oldmsg) in list(self.shown.keys()):
if net == irc.network and tgt == target:
if oldmsg.endswith(msg):
break
if msg.endswith(oldmsg) and msg[:-len(oldmsg)].endswith(': '):
msg = msg[:-len(oldmsg)] + 'Please see above'
else:
self.shown[(irc.network, target, msg)] = now
irc.reply(msg, to=target, private=True)
def get_target(self, irc, nick, text, target):
ret, retmsg = text, ''
orig_target = target
@ -411,7 +410,7 @@ class Encyclopedia(callbacks.Plugin):
def noqueue(irc, target, msg):
irc.reply(msg, to=target, private=True)
def myqueue(irc, target, msg):
(queue if queue_msg else noqueue)(irc, target, msg)
(self.queue if queue_msg else noqueue)(irc, target, msg)
# Filter CTCP
if chr(1) in msg.args[1]:

View File

@ -22,7 +22,7 @@ import supybot
import supybot.world as world
from importlib import reload
__version__ = "2.4.0"
__version__ = "2.5.0"
__author__ = supybot.Author("Krytarik Raido", "krytarik", "krytarik@gmail.com")
__contributors__ = {
supybot.Author("Dennis Kaarsemaker", "Seveas", "dennis@kaarsemaker.net"): ['Original Concept'],

View File

@ -47,30 +47,44 @@ deb-src deb http://security.debian.org/ %s/updates main contrib non-free
PackageInfo = conf.registerPlugin('PackageInfo', True)
enabled = yn("Enable this plugin in all channels?", default=True)
def getRepeatdelay():
output("How many seconds should the bot wait before repeating package information?")
repeatdelay = something("Enter a number greater or equal to 0.", default=PackageInfo.repeatdelay._default)
if enabled and advanced:
try:
repeatdelay = int(repeatdelay)
if repeatdelay < 0:
raise TypeError
except TypeError:
output("Invalid value '%s', it must be an integer greater or equal to 0." % repeatdelay)
return getRepeatdelay()
else:
return repeatdelay
enabled = yn("Enable this plugin in all channels?", default=PackageInfo.enabled._default)
if advanced:
prefixchar = something("Which prefix character should the bot respond to?", default=PackageInfo.prefixchar._default)
defaultRelease = something("What should be the default release when none is specified?", default=PackageInfo.defaultRelease._default)
repeatdelay = getRepeatdelay()
aptdir = something("Which directory should be used for the apt cache when looking up packages?", default=PackageInfo.aptdir._default)
# People tend to think this should be /var/cache/apt
while aptdir.startswith('/var'): #NOTE: This is not a good hack. Maybe just blacklist /var/cache/apt (or use apt to report back the cache dir)
output("NO! Do not use your system's apt directory")
aptdir = something("Which directory should be used for the apt cache when looking up packages?", default=PackageInfo.aptdir._default)
else:
prefixchar = PackageInfo.prefixchar._default
defaultRelease = PackageInfo.defaultRelease._default
repeatdelay = PackageInfo.repeatdelay._default
aptdir = PackageInfo.aptdir._default
PackageInfo.enabled.setValue(enabled)
PackageInfo.aptdir.setValue(aptdir)
PackageInfo.prefixchar.setValue(prefixchar)
PackageInfo.defaultRelease.setValue(defaultRelease)
PackageInfo.repeatdelay.setValue(repeatdelay)
PackageInfo.aptdir.setValue(aptdir)
default_dists = set(['bionic', 'focal', 'groovy', 'hirsute', 'impish',
default_dists = set(['bionic', 'focal', 'hirsute', 'impish', 'jammy',
'oldstable', 'stable', 'unstable', 'testing', 'experimental'])
pluginDir = os.path.abspath(os.path.dirname(__file__))
update_apt = os.path.join(pluginDir, 'update_apt')
@ -134,7 +148,10 @@ conf.registerChannelValue(PackageInfo, 'prefixchar',
conf.ValidPrefixChars('!', "Character the bot will respond to"))
conf.registerChannelValue(PackageInfo, 'defaultRelease',
registry.String('hirsute', "Default release to use when none is specified"))
registry.String('impish', "Default release to use when none is specified"))
conf.registerChannelValue(PackageInfo, 'repeatdelay',
registry.Integer(60, "Number of seconds to wait between repeated package info calls"))
conf.registerChannelValue(PackageInfo, 'listReleasesOnError',
registry.Boolean(True, "Send list of all valid releases in private on error"))

View File

@ -59,25 +59,6 @@ def checkIgnored(hostmask, channel):
return True
return False
## Taken from Encyclopedia ##
# Repeat filtering message queue
msgcache = {}
def queue(irc, target, msg):
now = time.time()
for m in list(msgcache.keys()):
if msgcache[m] < now - 30:
msgcache.pop(m)
for m in msgcache:
if m[0] == irc and m[1] == target:
oldmsg = m[2]
if oldmsg.endswith(msg):
break
if msg.endswith(oldmsg) and msg[:-len(oldmsg)].endswith(': '):
msg = msg[:-len(oldmsg)] + 'Please see above'
else:
msgcache[(irc, target, msg)] = now
irc.reply(msg, to=target, private=True)
class PackageInfo(callbacks.Plugin):
"""Look up package information via apt-cache/apt-file"""
threaded = True
@ -86,6 +67,7 @@ class PackageInfo(callbacks.Plugin):
self.__parent = super(PackageInfo, self)
self.__parent.__init__(irc)
self.Apt = packages.Apt(self)
self.shown = {}
def __getRelease(self, irc, release, channel, doError=True):
if release:
@ -136,6 +118,22 @@ class PackageInfo(callbacks.Plugin):
return (target, prefix + reply)
# Repeat filtering message queue
def queue(self, irc, target, msg):
now = time.time()
for m in list(self.shown.keys()):
if self.shown[m] < now - self.registryValue('repeatdelay', target, irc.network):
self.shown.pop(m)
for (net, tgt, oldmsg) in list(self.shown.keys()):
if net == irc.network and tgt == target:
if oldmsg.endswith(msg):
break
if msg.endswith(oldmsg) and msg[:-len(oldmsg)].endswith(': '):
msg = msg[:-len(oldmsg)] + 'Please see above'
else:
self.shown[(irc.network, target, msg)] = now
irc.reply(msg, to=target, private=True)
def info(self, irc, msg, args, package, release=None):
"""<[src:]package> [<release>]
@ -157,7 +155,7 @@ class PackageInfo(callbacks.Plugin):
reply = self.Apt.info(package, release, isSource)
if rest:
(target, reply) = self.__handleRest(irc, msg, target, reply, rest)
queue(irc, target, reply)
self.queue(irc, target, reply)
info = wrap(info, ['anything', optional('text')])
def depends(self, irc, msg, args, package, release=None):
@ -181,7 +179,7 @@ class PackageInfo(callbacks.Plugin):
reply = self.Apt.depends(package, release, isSource)
if rest:
(target, reply) = self.__handleRest(irc, msg, target, reply, rest)
queue(irc, target, reply)
self.queue(irc, target, reply)
depends = wrap(depends, ['anything', optional('text')])
def find(self, irc, msg, args, package, release=None):
@ -205,7 +203,7 @@ class PackageInfo(callbacks.Plugin):
reply = self.Apt.find(package, release)
if rest:
(target, reply) = self.__handleRest(irc, msg, target, reply, rest)
queue(irc, target, reply)
self.queue(irc, target, reply)
find = wrap(find, ['anything', optional('text')])
def releases(self, irc, msg, args):