### # Copyright (c) 2014, James Lu # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions, and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright notice, # this list of conditions, and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the author of this software nor the name of # contributors to this software may be used to endorse or promote products # derived from this software without specific prior written consent. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. ### import supybot.utils as utils from supybot.commands import * import supybot.plugins as plugins import supybot.ircutils as ircutils import supybot.callbacks as callbacks from collections import OrderedDict, defaultdict import urllib import json try: from supybot.i18n import PluginInternationalization _ = PluginInternationalization('PkgInfo') except ImportError: # Placeholder that allows to run the plugin on a bot # without the i18n module _ = lambda x:x class PkgInfo(callbacks.Plugin): """Fetches package information from the repositories of Debian, Arch Linux, and Ubuntu.""" threaded = True def __init__(self, irc): self.__parent = super(PkgInfo, self) self.__parent.__init__(irc) self.addrs = {'ubuntu':'http://packages.ubuntu.com/', 'debian':"http://packages.debian.org/"} def MadisonParse(self, pkg, dist, codenames='', suite=''): arch = ','.join(self.registryValue("archs")) self.arg = urllib.urlencode({'package':pkg,'table':dist,'a':arch,'c':codenames,'s':suite}) url = 'http://qa.debian.org/madison.php?text=on&' + self.arg d = OrderedDict() fd = utils.web.getUrlFd(url) for line in fd.readlines(): L = line.split("|") d[L[2].strip()] = (L[1].strip(),L[3].strip()) if d: if self.registryValue("verbose"): return 'Found %s results: ' % len(d) + ', '.join("{!s} " \ "\x02({!s} [{!s}])\x02".format(k,v[0],v[1]) for (k,v) in \ d.items()) return 'Found %s results: ' % len(d) + ', '.join("{!s} " \ "\x02({!s})\x02".format(k,v[0]) for (k,v) in d.items()) def package(self, irc, msg, args, suite, pkg): """ Fetches information for from Debian or Ubuntu's repositories. is the codename/release name (e.g. 'trusty', 'squeeze'). For Arch Linux packages, please use 'archpkg' and 'archaur' instead.""" d = self.MadisonParse(pkg, 'all', suite=suite) if not d: irc.error("No results found.",Raise=True) try: d += " View more at: {}search?keywords={}".format(self.addrs['distro'], pkg) except KeyError: pass irc.reply(d) package = wrap(package, ['somethingWithoutSpaces', 'somethingWithoutSpaces']) def vlist(self, irc, msg, args, distro, pkg): """ Fetches all available version of in , if such package exists. Supported entries for include: 'debian', 'ubuntu', 'derivatives', and 'all'.""" distro = distro.lower() d = self.MadisonParse(pkg, distro) if not d: irc.error("No results found.",Raise=True) try: d += " View more at: {}search?keywords={}".format(self.addrs['distro'], pkg) except KeyError: pass irc.reply(d) vlist = wrap(vlist, ['somethingWithoutSpaces', 'somethingWithoutSpaces']) def archpkg(self, irc, msg, args, pkg, opts): """ [--glob] Looks up in the Arch Linux package repositories. If --glob is given, the bot will search for as a glob instead of the exact package name. However, this often has the problem of giving many irrelevant results (e.g. 'git' will also match 'di git al'.""" baseurl = 'http://www.archlinux.org/packages/search/json/?' if 'glob' in dict(opts): fd = utils.web.getUrlFd(baseurl + urllib.urlencode({'q':pkg})) else: fd = utils.web.getUrlFd(baseurl + urllib.urlencode({'name':pkg})) data = json.load(fd) if data['valid'] and data['results']: f = set() archs = defaultdict(list) for x in data['results']: s = "{} - {} \x02({})\x02".format(x['pkgname'],x['pkgdesc'],x['pkgver']) f.add(s) archs[s].append(x['arch']) if self.registryValue("verbose"): irc.reply('Found %s results: ' % len(f)+', ' \ .join("{} \x02[{!s}]\x02".format(s, ', '.join(archs[s])) for s in f)) else: irc.reply('Found {} results: {}'.format(len(f),', '.join(f))) else: irc.error("No results found.",Raise=True) archpkg = wrap(archpkg, ['somethingWithoutSpaces', getopts({'glob':''})]) def archaur(self, irc, msg, args, pkg): """ Looks up in the Arch Linux AUR.""" baseurl = 'https://aur.archlinux.org/rpc.php?type=search&' fd = utils.web.getUrlFd(baseurl + urllib.urlencode({'arg':pkg})) data = json.load(fd) if data["type"] == "error": irc.error(data["results"], Raise=True) if data['resultcount']: s = "Found {} result{}: ".format(data["resultcount"], 's' if data["resultcount"] != 1 else '') for x in data['results']: verboseInfo = '' if self.registryValue("verbose"): verboseInfo = " [ID:{} Votes:{}]".format(x['ID'], x['NumVotes']) s += "{} - {} \x02({}{})\x02, ".format(x['Name'],x['Description'],x['Version'], verboseInfo) irc.reply(s[:-2]) else: irc.error("No results found.",Raise=True) archaur = wrap(archaur, ['somethingWithoutSpaces']) Class = PkgInfo # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: