mirror of
https://github.com/jlu5/SupyPlugins.git
synced 2025-05-02 16:31:11 -05:00
PkgInfo: abstract pkgsearch into fetcher backends (#64)
This commit is contained in:
parent
a7ad22cdbc
commit
a3e0b16d82
@ -155,17 +155,17 @@ class PkgInfo(callbacks.Plugin):
|
|||||||
'optdepends': '\x0312optdepends\x03'
|
'optdepends': '\x0312optdepends\x03'
|
||||||
})
|
})
|
||||||
|
|
||||||
def get_distro_fetcher(self, dist):
|
def get_distro_fetcher(self, dist, multi=False):
|
||||||
dist = dist.lower()
|
dist = dist.lower()
|
||||||
guess_dist = _guess_distro(dist)
|
guess_dist = _guess_distro(dist)
|
||||||
|
|
||||||
if dist == 'debian':
|
if dist == 'debian' and not multi:
|
||||||
raise AmbiguousDistributionError("You must specify a distribution version (e.g. 'stretch' or 'unstable')")
|
raise AmbiguousDistributionError("You must specify a distribution version (e.g. 'stretch' or 'unstable')")
|
||||||
elif dist == 'ubuntu':
|
elif dist == 'ubuntu' and not multi:
|
||||||
raise AmbiguousDistributionError("You must specify a distribution version (e.g. 'trusty' or 'xenial')")
|
raise AmbiguousDistributionError("You must specify a distribution version (e.g. 'trusty' or 'xenial')")
|
||||||
elif dist in ('mint', 'linuxmint'):
|
elif dist in ('mint', 'linuxmint'):
|
||||||
raise AmbiguousDistributionError("You must specify a distribution version (e.g. 'sonya' or 'betsy')")
|
raise AmbiguousDistributionError("You must specify a distribution version (e.g. 'sonya' or 'betsy')")
|
||||||
elif dist == 'fedora':
|
elif dist == 'fedora' and not multi:
|
||||||
raise AmbiguousDistributionError("You must specify a distribution version (e.g. 'f26', 'rawhide' or 'epel7')")
|
raise AmbiguousDistributionError("You must specify a distribution version (e.g. 'f26', 'rawhide' or 'epel7')")
|
||||||
elif dist == 'master':
|
elif dist == 'master':
|
||||||
raise AmbiguousDistributionError("'master' is ambiguous: for Fedora rawhide, use the release 'rawhide'")
|
raise AmbiguousDistributionError("'master' is ambiguous: for Fedora rawhide, use the release 'rawhide'")
|
||||||
@ -174,23 +174,26 @@ class PkgInfo(callbacks.Plugin):
|
|||||||
return self.arch_fetcher
|
return self.arch_fetcher
|
||||||
elif dist in ('archaur', 'aur'):
|
elif dist in ('archaur', 'aur'):
|
||||||
return self.arch_aur_fetcher
|
return self.arch_aur_fetcher
|
||||||
elif guess_dist == 'debian':
|
elif guess_dist == 'debian' or dist == 'debian':
|
||||||
return self.debian_fetcher
|
return self.debian_fetcher
|
||||||
elif dist in ('fbsd', 'freebsd'):
|
elif dist in ('fbsd', 'freebsd'):
|
||||||
return self.freebsd_fetcher
|
return self.freebsd_fetcher
|
||||||
elif guess_dist == 'ubuntu':
|
elif guess_dist == 'ubuntu' or dist == 'ubuntu':
|
||||||
return self.ubuntu_fetcher
|
return self.ubuntu_fetcher
|
||||||
elif guess_dist == 'mint':
|
elif guess_dist == 'mint':
|
||||||
return self.mint_fetcher
|
return self.mint_fetcher
|
||||||
elif dist.startswith(('f', 'el', 'epel', 'olpc', 'rawhide')):
|
elif dist.startswith(('f', 'el', 'epel', 'olpc', 'rawhide')):
|
||||||
return self.fedora_fetcher
|
return self.fedora_fetcher
|
||||||
|
|
||||||
def debian_fetcher(self, release, query, baseurl='https://packages.debian.org/', fetch_source=False, fetch_depends=False):
|
def debian_fetcher(self, release, query, baseurl='https://packages.debian.org/', fetch_source=False, fetch_depends=False, multi=False):
|
||||||
url = baseurl
|
url = baseurl
|
||||||
query = query.lower()
|
query = query.lower()
|
||||||
if fetch_source: # Source package was requested
|
if multi:
|
||||||
url += 'source/'
|
url += 'search?%s' % urlencode({'keywords': query})
|
||||||
url += "{}/{}".format(release, query)
|
else:
|
||||||
|
if fetch_source: # Source package was requested
|
||||||
|
url += 'source/'
|
||||||
|
url += "{}/{}".format(release, query)
|
||||||
|
|
||||||
text = utils.web.getUrl(url).decode("utf-8")
|
text = utils.web.getUrl(url).decode("utf-8")
|
||||||
|
|
||||||
@ -205,8 +208,11 @@ class PkgInfo(callbacks.Plugin):
|
|||||||
if "two or more packages specified" in err:
|
if "two or more packages specified" in err:
|
||||||
raise UnknownDistributionError("Unknown distribution/release.")
|
raise UnknownDistributionError("Unknown distribution/release.")
|
||||||
|
|
||||||
# If we're using the --depends option, handle that separately.
|
# If we're using the --depends or search options, handle that separately.
|
||||||
if fetch_depends:
|
if multi:
|
||||||
|
# Debian and Ubuntu use h3 for result names in the format 'Package abcd'
|
||||||
|
return [pkg.string.split()[1] for pkg in soup.find_all('h3')]
|
||||||
|
elif fetch_depends:
|
||||||
items = soup.find('div', {'id': 'pdeps'}).find_all('dl')
|
items = soup.find('div', {'id': 'pdeps'}).find_all('dl')
|
||||||
# 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,
|
||||||
# followed by recommends, suggests, and enhances.
|
# followed by recommends, suggests, and enhances.
|
||||||
@ -278,7 +284,7 @@ class PkgInfo(callbacks.Plugin):
|
|||||||
kwargs['baseurl'] = 'https://packages.ubuntu.com/'
|
kwargs['baseurl'] = 'https://packages.ubuntu.com/'
|
||||||
return self.debian_fetcher(*args, **kwargs)
|
return self.debian_fetcher(*args, **kwargs)
|
||||||
|
|
||||||
def arch_fetcher(self, release, query, fetch_source=False, fetch_depends=False):
|
def arch_fetcher(self, release, query, fetch_source=False, fetch_depends=False, multi=False):
|
||||||
search_url = 'https://www.archlinux.org/packages/search/json/?%s&arch=x86_64&arch=any' % urlencode({'name': query})
|
search_url = 'https://www.archlinux.org/packages/search/json/?%s&arch=x86_64&arch=any' % urlencode({'name': query})
|
||||||
|
|
||||||
self.log.debug("PkgInfo: using url %s for arch_fetcher", search_url)
|
self.log.debug("PkgInfo: using url %s for arch_fetcher", search_url)
|
||||||
@ -322,7 +328,7 @@ class PkgInfo(callbacks.Plugin):
|
|||||||
return # No results found!
|
return # No results found!
|
||||||
|
|
||||||
|
|
||||||
def arch_aur_fetcher(self, release, query, fetch_source=False, fetch_depends=False):
|
def arch_aur_fetcher(self, release, query, fetch_source=False, fetch_depends=False, multi=False):
|
||||||
search_url = 'https://aur.archlinux.org/rpc/?' + urlencode(
|
search_url = 'https://aur.archlinux.org/rpc/?' + urlencode(
|
||||||
{'arg[]': query, 'v': 5,'type': 'info'}
|
{'arg[]': query, 'v': 5,'type': 'info'}
|
||||||
)
|
)
|
||||||
@ -388,7 +394,7 @@ class PkgInfo(callbacks.Plugin):
|
|||||||
# XXX: find some way to fetch the package version, as pkgdb's api doesn't provide that info
|
# XXX: find some way to fetch the package version, as pkgdb's api doesn't provide that info
|
||||||
return (result['name'], 'some version, see URL for details', release, result['description'].replace('\n', ' '), friendly_url)
|
return (result['name'], 'some version, see URL for details', release, result['description'].replace('\n', ' '), friendly_url)
|
||||||
|
|
||||||
def mint_fetcher(self, release, query, fetch_source=False, fetch_depends=False):
|
def mint_fetcher(self, release, query, fetch_source=False, fetch_depends=False, multi=False):
|
||||||
if fetch_depends:
|
if fetch_depends:
|
||||||
raise UnsupportedOperationError("--depends lookup is not supported for Linux Mint")
|
raise UnsupportedOperationError("--depends lookup is not supported for Linux Mint")
|
||||||
|
|
||||||
@ -432,7 +438,7 @@ class PkgInfo(callbacks.Plugin):
|
|||||||
return (query, ', '.join('%s: %s' % (k, v) for k, v in versions.items()),
|
return (query, ', '.join('%s: %s' % (k, v) for k, v in versions.items()),
|
||||||
'Linux Mint %s' % release.title(), 'no description available', addr)
|
'Linux Mint %s' % release.title(), 'no description available', addr)
|
||||||
|
|
||||||
def freebsd_fetcher(self, release, query, fetch_source=False, fetch_depends=False):
|
def freebsd_fetcher(self, release, query, fetch_source=False, fetch_depends=False, multi=False):
|
||||||
if fetch_source:
|
if fetch_source:
|
||||||
raise UnsupportedOperationError("--source lookup is not supported for FreeBSD")
|
raise UnsupportedOperationError("--source lookup is not supported for FreeBSD")
|
||||||
|
|
||||||
@ -470,16 +476,16 @@ class PkgInfo(callbacks.Plugin):
|
|||||||
instead of a binary.
|
instead of a binary.
|
||||||
|
|
||||||
This command replaces the 'fedora', 'archlinux', and 'archaur' commands from earlier versions of PkgInfo."""
|
This command replaces the 'fedora', 'archlinux', and 'archaur' commands from earlier versions of PkgInfo."""
|
||||||
|
|
||||||
distro_fetcher = self.get_distro_fetcher(dist)
|
|
||||||
if distro_fetcher is None:
|
|
||||||
irc.error("Unknown distribution version %r" % dist, Raise=True)
|
|
||||||
|
|
||||||
opts = dict(opts)
|
opts = dict(opts)
|
||||||
fetch_source = 'source' in opts
|
fetch_source = 'source' in opts
|
||||||
fetch_depends = 'depends' in opts
|
fetch_depends = 'depends' in opts
|
||||||
|
multi = 'search' in opts
|
||||||
|
|
||||||
result = distro_fetcher(dist, query, fetch_source=fetch_source, fetch_depends=fetch_depends)
|
distro_fetcher = self.get_distro_fetcher(dist, multi=multi)
|
||||||
|
if distro_fetcher is None:
|
||||||
|
irc.error("Unknown distribution version %r" % dist, Raise=True)
|
||||||
|
|
||||||
|
result = distro_fetcher(dist, query, fetch_source=fetch_source, fetch_depends=fetch_depends, multi=multi)
|
||||||
if not result:
|
if not result:
|
||||||
irc.error("Unknown package %r" % query, Raise=True)
|
irc.error("Unknown package %r" % query, Raise=True)
|
||||||
|
|
||||||
@ -507,14 +513,28 @@ class PkgInfo(callbacks.Plugin):
|
|||||||
else:
|
else:
|
||||||
if not isinstance(result, (list, tuple)):
|
if not isinstance(result, (list, tuple)):
|
||||||
raise UnsupportedOperationError("Internal fetcher error (wrong output type; expected list or tuple but got %s)" % (type(result).__name__))
|
raise UnsupportedOperationError("Internal fetcher error (wrong output type; expected list or tuple but got %s)" % (type(result).__name__))
|
||||||
# result is formatted in the order: packagename, version, real_distribution, desc, url
|
|
||||||
self.log.debug('PkgInfo result args: %s', str(result))
|
if multi:
|
||||||
s = format("Package: \x02%s (%s)\x02 in %s - %s %u", *result)
|
s = format("Found \x02%s\x02 results: %L", len(result), (ircutils.bold(r) for r in result))
|
||||||
irc.reply(s)
|
irc.reply(s)
|
||||||
|
else:
|
||||||
|
# result is formatted in the order: packagename, version, real_distribution, desc, url
|
||||||
|
self.log.debug('PkgInfo result args: %s', str(result))
|
||||||
|
s = format("Package: \x02%s (%s)\x02 in %s - %s %u", *result)
|
||||||
|
irc.reply(s)
|
||||||
|
|
||||||
pkg = wrap(package, ['somethingWithoutSpaces', 'somethingWithoutSpaces',
|
pkg = wrap(package, ['somethingWithoutSpaces', 'somethingWithoutSpaces',
|
||||||
getopts({'depends': '', 'source': ''})])
|
getopts({'depends': '', 'source': ''})])
|
||||||
|
|
||||||
|
def pkgsearch(self, irc, msg, args, dist, query):
|
||||||
|
"""<distro> <query>
|
||||||
|
|
||||||
|
Looks up <query> in <distro>'s website. Valid <distro>'s include
|
||||||
|
'debian', 'ubuntu', and 'debian-archive'."""
|
||||||
|
return self.package(irc, msg, args, dist, query, {'search': True})
|
||||||
|
pkgsearch = wrap(pkgsearch, ['somethingWithoutSpaces',
|
||||||
|
'somethingWithoutSpaces'])
|
||||||
|
|
||||||
def vlist(self, irc, msg, args, distro, pkg, opts):
|
def vlist(self, irc, msg, args, distro, pkg, opts):
|
||||||
"""<distribution> <package> [--reverse]
|
"""<distribution> <package> [--reverse]
|
||||||
|
|
||||||
@ -627,49 +647,6 @@ class PkgInfo(callbacks.Plugin):
|
|||||||
irc.error("No results found.", Raise=True)
|
irc.error("No results found.", Raise=True)
|
||||||
archaur = wrap(archaur, ['somethingWithoutSpaces'])
|
archaur = wrap(archaur, ['somethingWithoutSpaces'])
|
||||||
|
|
||||||
def pkgsearch(self, irc, msg, args, distro, query):
|
|
||||||
"""<distro> <query>
|
|
||||||
|
|
||||||
Looks up <query> in <distro>'s website. Valid <distro>'s include
|
|
||||||
'debian', 'ubuntu', and 'debian-archive'."""
|
|
||||||
distro = distro.lower()
|
|
||||||
if distro not in addrs.keys():
|
|
||||||
distro = _guess_distro(distro)
|
|
||||||
try:
|
|
||||||
url = '%ssearch?keywords=%s' % (addrs[distro], quote(query))
|
|
||||||
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)
|
|
||||||
# Debian/Ubuntu use h3 for result names in the format 'Package abcd'
|
|
||||||
results = [pkg.string.split()[1] for pkg in soup.find_all('h3')]
|
|
||||||
if results:
|
|
||||||
s = format("Found %n: \x02%L\x02, View more at: %u",
|
|
||||||
(len(results), 'result'), results, url)
|
|
||||||
irc.reply(s)
|
|
||||||
else:
|
|
||||||
e = "No results found."
|
|
||||||
try:
|
|
||||||
# Look for "too many results" errors and others reported by the
|
|
||||||
# web interface.
|
|
||||||
if distro == "debian":
|
|
||||||
errorParse = soup.find("div", class_="note").p
|
|
||||||
else:
|
|
||||||
errorParse = soup.find("p", attrs={"id":
|
|
||||||
"psearchtoomanyhits"})
|
|
||||||
if errorParse:
|
|
||||||
for br in errorParse.findAll('br'):
|
|
||||||
br.replace_with(" ")
|
|
||||||
e = errorParse.text.strip()
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
irc.error(e)
|
|
||||||
pkgsearch = wrap(pkgsearch, ['somethingWithoutSpaces',
|
|
||||||
'somethingWithoutSpaces'])
|
|
||||||
|
|
||||||
@wrap(['somethingWithoutSpaces', 'somethingWithoutSpaces'])
|
@wrap(['somethingWithoutSpaces', 'somethingWithoutSpaces'])
|
||||||
def filesearch(self, irc, msg, args, release, query):
|
def filesearch(self, irc, msg, args, release, query):
|
||||||
"""<release> <file query>
|
"""<release> <file query>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user