Compare commits

...

5 Commits

Author SHA1 Message Date
Krytarik Raido f9066b25c0 Encyclopedia: Rename setting 'alert' → 'alerts' 2022-10-13 00:17:04 +02:00
Krytarik Raido 8d2bb1f371 Encyclopedia: Drop private responses off settings.
Since there is nothing really sensitive about them anyway,
and it helps configuring multiple bot instances at once.
2022-10-12 23:56:04 +02:00
Krytarik Raido f2ea4477c0 Bugtracker: More exactly trim CVE information. 2022-10-11 03:34:04 +02:00
Krytarik Raido bfa65ed8c3 Encyclopedia, PackageInfo: Add '!more' command.
So unprivileged users can page through multi-message outputs.

Also make PackageInfo stop processing requests twice in case of
privileged users PM'ing the bot with unprefixed commands, and make it
possible to address the bot with prefixed commands for unprivileged use.
2022-10-10 23:56:04 +02:00
Krytarik Raido cccf339e2e Bugtracker: Add option to send bug information via notice. 2022-10-01 16:45:04 +02:00
11 changed files with 74 additions and 36 deletions

View File

@ -36,7 +36,7 @@ import supybot
from supybot import world
# Use this for the version of this plugin.
__version__ = "1.0.0"
__version__ = "1.0.1"
# XXX Replace this with an appropriate author or supybot.Author instance.
__author__ = supybot.Author('Krytarik Raido', 'krytarik', 'krytarik@gmail.com')

View File

@ -59,7 +59,7 @@ conf.registerNetworkValue(Bugreporter, 'channels',
registry.SpaceSeparatedListOfStrings([], _("""Channels to announce bug reports to.""")))
conf.registerChannelValue(Bugreporter, 'projects',
registry.SpaceSeparatedListOfStrings(['ubuntu'], _("""Projects to announce bug reports on.""")))
registry.SpaceSeparatedListOfStrings(['ubuntu'], _("""Projects to announce bug reports on.""")))
conf.registerChannelValue(Bugreporter, 'useNotices',
registry.Boolean(False, _("""Use notices instead of normal messages.""")))
registry.Boolean(False, _("""Use notices instead of normal messages.""")))

View File

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

View File

@ -71,6 +71,7 @@ def configure(advanced):
showassignee = yn("Show the assignee of a bug in the reply?", default=Bugtracker.showassignee._default)
extended = yn("Show tracker-specific extended infomation?", default=Bugtracker.extended._default)
useNotices = yn("Use notices instead of normal messages to send bug information?", default=Bugtracker.useNotices._default)
saveDiscoveredTrackers = yn("Save automatically discovered trackers to configuration?", default=Bugtracker.saveDiscoveredTrackers._default)
Bugtracker.bugSnarfer.setValue(bugSnarfer)
@ -84,6 +85,7 @@ def configure(advanced):
Bugtracker.repeatdelay.setValue(repeatdelay)
Bugtracker.showassignee.setValue(showassignee)
Bugtracker.extended.setValue(extended)
Bugtracker.useNotices.setValue(useNotices)
Bugtracker.saveDiscoveredTrackers.setValue(saveDiscoveredTrackers)
Bugtracker = conf.registerPlugin('Bugtracker')
@ -129,11 +131,14 @@ conf.registerChannelValue(Bugtracker, 'repeatdelay',
registry.Integer(60, """Number of seconds to wait between repeated bug calls"""))
conf.registerChannelValue(Bugtracker, 'showassignee',
registry.Boolean(False, """Whether to show the assignee in bug reports"""))
registry.Boolean(False, """Whether to show the assignee in bug information"""))
conf.registerChannelValue(Bugtracker, 'extended',
registry.Boolean(False, """Whether to show extended bug information, specific to trackers"""))
conf.registerChannelValue(Bugtracker, 'useNotices',
registry.Boolean(False, """Whether to use notices instead of normal messages to send bug information"""))
conf.registerGlobalValue(Bugtracker, 'saveDiscoveredTrackers',
registry.Boolean(False, """Whether to save automatically discovered trackers to configuration"""))

View File

@ -412,7 +412,10 @@ class Bugtracker(callbacks.PluginRegexp):
irc.error(str(e))
else:
if report:
irc.reply(report)
if not self.registryValue('useNotices', channel, irc.network):
irc.reply(report)
else:
irc.reply(report, notice=True)
def bugUrlSnarfer(self, irc, msg, match):
r"(https?://)?((bugs\.debian\.org|pad\.lv)/|\S+/(show_bug\.cgi\?id=|bugreport\.cgi\?bug=|view\.php\?id=|bug=|bugs/|\+bug/|tickets?/|feature-requests/|patches/|todo/|issues/|pulls?/|merge_requests/))(?P<bug>\d+)"
@ -452,7 +455,10 @@ class Bugtracker(callbacks.PluginRegexp):
irc.error(str(e))
else:
if report:
irc.reply(report)
if not self.registryValue('useNotices', channel, irc.network):
irc.reply(report)
else:
irc.reply(report, notice=True)
# Only useful to Launchpad developers
def oopsSnarfer(self, irc, msg, match):
@ -467,7 +473,11 @@ class Bugtracker(callbacks.PluginRegexp):
if not self.is_ok(channel or msg.nick, irc.network, 'lpoops', oopsid):
return
if not match.group(1):
irc.reply('https://oops.canonical.com/?oopsid=OOPS-%s' % oopsid)
report = 'https://oops.canonical.com/?oopsid=OOPS-%s' % oopsid
if not self.registryValue('useNotices', channel, irc.network):
irc.reply(report)
else:
irc.reply(report, notice=True)
def cveSnarfer(self, irc, msg, match):
r"(https?://\S+=)?CVE[- ](?P<cveid>\d{4}[- ]\d{4,})"
@ -485,7 +495,7 @@ class Bugtracker(callbacks.PluginRegexp):
else:
do_url = False
try:
report = trackers.CVE().get_bug(cveid, do_url)
report = trackers.CVE().get_bug(channel or msg.nick, cveid, do_url)
except trackers.BugNotFoundError:
if self.registryValue('replyWhenNotFound'):
irc.error("Could not find CVE %s" % cveid)
@ -494,7 +504,10 @@ class Bugtracker(callbacks.PluginRegexp):
irc.error(str(e))
else:
if report:
irc.reply(report)
if not self.registryValue('useNotices', channel, irc.network):
irc.reply(report)
else:
irc.reply(report, notice=True)
#TODO: As we will depend on launchpadlib, we should consider using lazr.uri.URI to do URL parsing
def get_tracker(self, snarfurl, bugid):

View File

@ -72,7 +72,7 @@ cvere = re.compile(r'<th[^>]*>Description</th>.*?<td[^>]*>\s*(?P<cve>.*?)\s*</td
cverre = re.compile(r'<h2[^>]*>\s*(?P<cverr>.*?)\s*</h2>', re.I | re.DOTALL)
# Define CVE tracker
class CVE:
def get_bug(self, cveid, do_url=True):
def get_bug(self, channel, cveid, do_url=True):
url = "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-%s" % cveid
try:
cvedata = utils.web.getUrl(url).decode('utf-8')
@ -81,8 +81,11 @@ class CVE:
match = cvere.search(cvedata)
if match:
cve = utils.web.htmlToText(match.group('cve'), tagReplace='')
if len(cve) > 380:
cve = cve[:380] + '...'
desc_max = 450 - len(channel)
if do_url:
desc_max -= len(url) + 3
if len(cve) > desc_max:
cve = cve[:desc_max-3] + '...'
if do_url:
cve += ' <%s>' % url
return cve

View File

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

View File

@ -87,12 +87,12 @@ def configure(advanced):
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 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([])
alerts = set([])
output("When certain factoids are called an alert can be forwarded to a channel/nick")
output("Which factoids should the bot forward alert calls for?")
alert_i = anything("Separate types by spaces or commas:", default=', '.join(Encyclopedia.alert._default))
for name in re.split(r'[,\s]+', alert_i):
alert.add(name.lower())
alerts_i = anything("Separate names by spaces or commas:", default=', '.join(Encyclopedia.alerts._default))
for name in re.split(r'[,\s]+', alerts_i):
alerts.add(name.lower())
remotedb = anything("Location of a remote database to sync with (used with @sync):", default=Encyclopedia.remotedb._default)
privateNotFound = yn("Should the bot reply in private when a factoid is not found, as opposed to in the channel?", default=Encyclopedia.privateNotFound._default)
@ -112,7 +112,7 @@ def configure(advanced):
Encyclopedia.curLTSNum.setValue(curLTSNum)
Encyclopedia.relaychannel.setValue(relaychannel)
Encyclopedia.notfoundmsg.setValue(notfoundmsg)
Encyclopedia.alert.setValue(alert)
Encyclopedia.alerts.setValue(alerts)
Encyclopedia.remotedb.setValue(remotedb)
Encyclopedia.privateNotFound.setValue(privateNotFound)
@ -196,16 +196,16 @@ conf.registerChannelValue(Encyclopedia,'prefixchar',
registry.String('!', 'Character the bot will respond to factoid requests with'))
conf.registerGlobalValue(Encyclopedia, 'datadir',
conf.Directory(conf.supybot.directories.data(), 'Directory containing factoid databases', private=True))
conf.Directory(conf.supybot.directories.data(), 'Directory containing factoid databases'))
conf.registerChannelValue(Encyclopedia, 'alert',
registry.SpaceSeparatedListOfStrings(['ops', 'op', 'kops', 'calltheops'], 'Factoid names used for alerts', private=True))
conf.registerChannelValue(Encyclopedia, 'alerts',
registry.SpaceSeparatedListOfStrings(['ops', 'op', 'kops', 'calltheops'], 'Factoid names used for alerts'))
conf.registerChannelValue(Encyclopedia, 'remotedb',
registry.String('https://ubottu.com/ubuntu.db', 'Remote location of the master database', private=True))
registry.String('https://ubottu.com/ubuntu.db', 'Remote location of the master database'))
conf.registerChannelValue(Encyclopedia, 'ignores',
registry.SpaceSeparatedListOfStrings(['info', 'depends', 'find'], 'Factoid names to ignore', private=True))
registry.SpaceSeparatedListOfStrings(['info', 'depends', 'find', 'more'], 'Factoid names to ignore'))
conf.registerChannelValue(Encyclopedia, 'repeatdelay',
registry.Integer(60, "Number of seconds to wait between repeated factoid calls"))

View File

@ -335,7 +335,7 @@ class Encyclopedia(callbacks.Plugin):
return
if loop >= 10:
return "Error: Infinite <alias> loop detected"
if factoid.name in self.registryValue('alert', channel):
if factoid.name in self.registryValue('alerts', channel):
self.alert = True
if factoid.value.startswith('<alias>'):
alias_name = factoid.value[7:].strip()
@ -432,17 +432,21 @@ class Encyclopedia(callbacks.Plugin):
if not channel:
args = text.lower().split(None, 2)
for c in irc.callbacks:
if (args[0] == c.name().lower() and len(args) > 1
and c.isCommandMethod(args[1])) \
or c.isCommandMethod(args[0]):
return
if args[0] != "more":
for c in irc.callbacks:
if (args[0] == c.name().lower() and len(args) > 1
and c.isCommandMethod(args[1])) \
or c.isCommandMethod(args[0]):
return
prefixchar = self.registryValue('prefixchar', channel)
prefixed = False
if text[0] == prefixchar:
text = text[1:].strip()
prefixed = True
elif re.match(r'^%s[\W\s]\s*%s' % (re.escape(irc.nick), re.escape(prefixchar)), text, re.I):
text = re.sub(r'^%s[\W\s]\s*%s\s*' % (re.escape(irc.nick), re.escape(prefixchar)), '', text, flags=re.I)
prefixed = True
elif channel:
return
if not text:
@ -479,6 +483,10 @@ class Encyclopedia(callbacks.Plugin):
ret = "Search factoids for term: !search <term>"
target = term[1]
retmsg = term[2]
elif lower_term == "more":
if prefixed or defaultIgnored(msg.prefix):
callbacks.NestedCommandsIrcProxy(irc, msg, ["Misc", "more"])
return
elif re.match(r"^seen\b", lower_term): # Some people expect a '!seen <nick>' command
ret = "I have no seen command"
retmsg = "%s: " % msg.nick if term[2] else '' # Redirect back at the caller, rather than the target

View File

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

View File

@ -221,20 +221,29 @@ class PackageInfo(callbacks.Plugin):
if not text:
return
channel = msg.channel
if text[0] == self.registryValue("prefixchar", channel, irc.network):
prefixchar = self.registryValue("prefixchar", channel, irc.network)
prefixed = False
if text[0] == prefixchar:
text = text[1:].strip()
prefixed = True
elif re.match(r'^%s[\W\s]\s*%s' % (re.escape(irc.nick), re.escape(prefixchar)), text, re.I):
text = re.sub(r'^%s[\W\s]\s*%s\s*' % (re.escape(irc.nick), re.escape(prefixchar)), '', text, flags=re.I)
prefixed = True
elif channel or text[0] in conf.supybot.reply.whenAddressedBy.chars():
return
if not (prefixed or defaultIgnored(msg.prefix)):
return
if not text:
return
(cmd, rest) = (text.split(None, 1) + [None])[:2]
if not cmd:
return
cmd = cmd.lower()
if not (cmd in ("info", "depends", "find") and rest):
return
(package, release) = (rest.split(None, 1) + [''])[:2]
callbacks.NestedCommandsIrcProxy(irc, msg, ["PackageInfo", cmd, package, release])
if cmd in ("info", "depends", "find") and rest:
(package, release) = (rest.split(None, 1) + [''])[:2]
callbacks.NestedCommandsIrcProxy(irc, msg, ["PackageInfo", cmd, package, release])
elif cmd == "more":
callbacks.NestedCommandsIrcProxy(irc, msg, ["Misc", "more"])
def inFilter(self, irc, msg):
if not (msg.prefix and msg.args):