PkgInfo: add 'filesearch' for searching contents in Debian/Ubuntu

This commit is contained in:
James Lu 2016-09-05 20:17:44 -07:00
parent 5ac44e54d4
commit 7e8bf6ab17
2 changed files with 48 additions and 2 deletions

View File

@ -102,6 +102,7 @@ addrs = {'ubuntu': 'http://packages.ubuntu.com/',
'debian': 'https://packages.debian.org/', 'debian': 'https://packages.debian.org/',
# This site is very, VERY slow, but it still works.. # This site is very, VERY slow, but it still works..
'debian-archive': 'http://archive.debian.net/'} 'debian-archive': 'http://archive.debian.net/'}
_normalize = lambda text: utils.str.normalizeWhitespace(text).strip()
def _getDistro(release): def _getDistro(release):
"""<release> """<release>
@ -169,7 +170,7 @@ class PkgInfo(callbacks.Plugin):
irc.reply(err) irc.reply(err)
return return
# If we're using the --depends option, handle that separately. # If we're using the --depends option, handle that separately.
if 'depends' in opts: if 'depends' in opts:
items = soup.find('div', {'id': 'pdeps'}).find_all('dt') items = soup.find('div', {'id': 'pdeps'}).find_all('dt')
# Store results by type and name, but in an ordered fashion: show dependencies first, # Store results by type and name, but in an ordered fashion: show dependencies first,
@ -390,6 +391,48 @@ class PkgInfo(callbacks.Plugin):
pkgsearch = wrap(pkgsearch, ['somethingWithoutSpaces', pkgsearch = wrap(pkgsearch, ['somethingWithoutSpaces',
'somethingWithoutSpaces']) 'somethingWithoutSpaces'])
@wrap(['somethingWithoutSpaces', 'somethingWithoutSpaces'])
def filesearch(self, irc, msg, args, release, query):
"""<release> <file query>
Searches what package in Debian or Ubuntu has which file. <release> is the
codename/release name (e.g. xenial or jessie)."""
release = release.lower()
distro = _getDistro(release)
try:
url = '%ssearch?keywords=%s&searchon=contents&suite=%s' % (addrs[distro], quote(query), quote(release))
except KeyError:
irc.error(unknowndist, Raise=True)
try:
fd = utils.web.getUrl(url).decode("utf-8")
except utils.web.Error as e:
irc.error(str(e), Raise=True)
soup = BeautifulSoup(fd)
results = []
# Get results from table entries, minus the first one which is used for headings.
contentdiv = soup.find('div', attrs={'id': "pcontentsres"})
if contentdiv:
for tr in contentdiv.find_all("tr")[1:]:
tds = tr.find_all('td')
try:
filename, packages = map(_normalize, [tds[0].get_text(), tds[1].get_text()])
except IndexError:
continue
results.append('%s: %s' % (ircutils.bold(filename), packages))
if results:
irc.reply('; '.join(results))
else:
try:
e = _normalize(soup.find("div", class_="perror").get_text())
except AttributeError:
e = "No results found."
irc.error(e)
@wrap(['somethingWithoutSpaces', @wrap(['somethingWithoutSpaces',
'somethingWithoutSpaces', 'somethingWithoutSpaces',
getopts({'exact': ''})]) getopts({'exact': ''})])

View File

@ -1,5 +1,5 @@
### ###
# Copyright (c) 2014-2015, James Lu # Copyright (c) 2014-2016, James Lu
# All rights reserved. # All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
@ -67,6 +67,9 @@ class PkgInfoTestCase(PluginTestCase):
def testPkgsearch(self): def testPkgsearch(self):
self.assertRegexp('pkgsearch debian python', 'python') self.assertRegexp('pkgsearch debian python', 'python')
def testFilesearch(self):
self.assertRegexp('filesearch sid supybot', 'limnoria')
def testFedora(self): def testFedora(self):
self.assertRegexp('fedora 22 bash*', 'bash') self.assertRegexp('fedora 22 bash*', 'bash')
# Not found queries that don't have any wildcards in them # Not found queries that don't have any wildcards in them