From 413a9961d45c0b45ab3c050a88dc4509b2c3abdb Mon Sep 17 00:00:00 2001 From: James Lu Date: Tue, 14 Jun 2016 19:43:04 -0700 Subject: [PATCH] PkgInfo: tweaks to 'centos' Make repository name optional, so they can be listed if only the release number is given. Fix --exact and add a --startswith filter option for packages. --- PkgInfo/plugin.py | 95 +++++++++++++++++++++++++++++++---------------- 1 file changed, 62 insertions(+), 33 deletions(-) diff --git a/PkgInfo/plugin.py b/PkgInfo/plugin.py index d70094f..fe4ccfb 100644 --- a/PkgInfo/plugin.py +++ b/PkgInfo/plugin.py @@ -454,55 +454,84 @@ class PkgInfo(callbacks.Plugin): friendly_url) irc.reply(s) - @wrap(['positiveInt', 'somethingWithoutSpaces', 'somethingWithoutSpaces', - getopts({'arch': 'somethingWithoutSpaces'})]) + @wrap(['positiveInt', additional('somethingWithoutSpaces'), additional('somethingWithoutSpaces'), + getopts({'arch': 'somethingWithoutSpaces', 'exact': '', 'startswith': ''})]) def centos(self, irc, msg, args, release, repo, query, opts): - """ [--arch ] + """ [ ] [--arch ] [--startswith|--exact] Looks up in CentOS's repositories. is the release version (6, 7, etc.), and is the repository name. You can find a list of possible repository names here: http://mirror.centos.org/centos/7/ (each folder is a repository). - Supported values for include x86_64 and i386 (prior to CentOS 7)""" - # CentOS doesn't have a package lookup interface, but only an autoindexed - # file server... - arch = dict(opts).get('arch') or 'x86_64' - query = query.lower() - # Different CentOS versions use different paths for their pool, ugh. - for folder in ('Packages', 'RPMS', 'openstack-juno', 'openstack-kilo', - 'CentOS'): - url = 'http://mirror.centos.org/centos/%s/%s/%s/%s/' % \ - (release, repo, arch, folder) - self.log.debug("PkgInfo: trying url %s for 'centos' command", url) - try: - fd = utils.web.getUrl(url).decode("utf-8") - except utils.web.Error: - continue + + Supported values for include x86_64 and i386 (prior to CentOS 7), + and defaults to x86_64. + + If is not given, a list of available ones will be shown instead. + + If --startswith is given, results starting with the given query are shown. If --exact + is given, only exact matches are shown.""" + + # TL;DR CentOS doesn't have a package lookup interface, but only an autoindexed + # file server... We must find all repositories, package URLs, etc. that way. + opts = dict(opts) + exact = opts.get('exact') + startswith = opts.get('startswith') + arch = opts.get('arch') or 'x86_64' + + url = 'http://mirror.centos.org/centos/%s' % release + if repo: + if query: + query = query.lower() + # Both repo and package name were given, so look in folders there. + # Note: different CentOS versions different paths for their pool, ugh. + for folder in ('Packages', 'RPMS', 'openstack-juno', 'openstack-kilo', + 'CentOS'): + url = 'http://mirror.centos.org/centos/%s/%s/%s/%s/' % \ + (release, repo, arch, folder) + self.log.debug("PkgInfo: trying url %s for 'centos' command", url) + try: + fd = utils.web.getUrl(url).decode("utf-8") + except utils.web.Error: + continue + else: + break + else: + irc.error('Unknown repository %r.' % repo, Raise=True) else: - break - else: - irc.error('Unknown repository %r.' % repo, Raise=True) + # Giving a repository but no package name is useless. Usually there + # are too many results to display without filtering anyways. + irc.error("Missing package query.", Raise=True) + else: # No repository given; list the ones available. + fd = utils.web.getUrl(url).decode("utf-8") + soup = BeautifulSoup(fd) # The first two tables are for the navigation bar; the third is the actual autoindex # content. res = [] packagetable = soup.find_all('table')[2] - exact = 'exact' in dict(opts) - for tr in packagetable.find_all('tr'): + + for tr in packagetable.find_all('tr')[3:]: try: - package = tr.find_all('td')[1].a.text + entry = tr.find_all('td')[1].a.text except IndexError: continue - if not package.endswith('.rpm'): - # Prevent things like "Parent Directory" from appearing in results + + entry = entry.lower() + if not query: # No query filter given; show everything. + res.append(entry) + elif exact: + if query == entry: # Exact match + res.append(entry) + continue + elif startswith: + if entry.startswith(query): # startswith() match + res.append(entry) + continue + elif query in entry: # Default substring search + res.append(entry) continue - package = ircutils.bold(package) - if exact: - if query == package.lower(): - res.append(package) - else: - if query in package.lower(): - res.append(package) + if res: irc.reply(format('Found %n: %L; View more at: %u', (len(res), 'result'), res, url)) else: