This commit is contained in:
James Lu 2014-10-16 18:39:55 -07:00
commit a276036e75
4 changed files with 76 additions and 7 deletions

View File

@ -1,5 +1,7 @@
Fetches package information from the repositories of Debian, Arch Linux, and Ubuntu. Fetches package information from the repositories of Debian, Arch Linux, Linux Mint, and Ubuntu.
This plugin uses the following APIs: This plugin uses the following APIs:
- For Debian and Ubuntu, Debian's [madison.php](//qa.debian.org/madison.php) (for 'vlist') - For Debian and Ubuntu, Debian's [madison.php](//qa.debian.org/madison.php) (used for 'vlist' command)
- For Arch Linux and its AUR, [AurJson](//wiki.archlinux.org/index.php/AurJson) and the [Arch Linux Repository Web Interface](//wiki.archlinux.org/index.php/Official_Repositories_Web_Interface) - For Arch Linux and its AUR, [AurJson](//wiki.archlinux.org/index.php/AurJson) and the [Arch Linux Repository Web Interface](//wiki.archlinux.org/index.php/Official_Repositories_Web_Interface)
Everything else is parsed as HTML using the Beautiful Soup 4 library.

View File

@ -68,12 +68,12 @@ class PkgInfo(callbacks.Plugin):
self.__parent = super(PkgInfo, self) self.__parent = super(PkgInfo, self)
self.__parent.__init__(irc) self.__parent.__init__(irc)
self.addrs = {'ubuntu':'http://packages.ubuntu.com/', self.addrs = {'ubuntu':'http://packages.ubuntu.com/',
'debian':"http://packages.debian.org/"} 'debian':"https://packages.debian.org/"}
def MadisonParse(self, pkg, dist, codenames='', suite=''): def MadisonParse(self, pkg, dist, codenames='', suite=''):
arch = ','.join(self.registryValue("archs")) arch = ','.join(self.registryValue("archs"))
self.arg = urlencode({'package':pkg,'table':dist,'a':arch,'c':codenames,'s':suite}) self.arg = urlencode({'package':pkg,'table':dist,'a':arch,'c':codenames,'s':suite})
url = 'http://qa.debian.org/madison.php?text=on&' + self.arg url = 'https://qa.debian.org/madison.php?text=on&' + self.arg
d = OrderedDict() d = OrderedDict()
fd = utils.web.getUrlFd(url) fd = utils.web.getUrlFd(url)
for line in fd.readlines(): for line in fd.readlines():
@ -143,7 +143,7 @@ class PkgInfo(callbacks.Plugin):
Looks up <package> in the Arch Linux package repositories. Looks up <package> in the Arch Linux package repositories.
If --exact is given, will output only exact matches. If --exact is given, will output only exact matches.
""" """
baseurl = 'http://www.archlinux.org/packages/search/json/?' baseurl = 'https://www.archlinux.org/packages/search/json/?'
if 'exact' in dict(opts): if 'exact' in dict(opts):
fd = utils.web.getUrl(baseurl + urlencode({'name':pkg})) fd = utils.web.getUrl(baseurl + urlencode({'name':pkg}))
else: else:
@ -209,6 +209,49 @@ class PkgInfo(callbacks.Plugin):
irc.reply(s) irc.reply(s)
pkgsearch = wrap(pkgsearch, ['somethingWithoutSpaces', 'somethingWithoutSpaces']) pkgsearch = wrap(pkgsearch, ['somethingWithoutSpaces', 'somethingWithoutSpaces'])
def mintpkg(self, irc, msg, args, release, query, opts):
"""<release> <package> [--exact]
Looks up <package> in Linux Mint's repositories."""
if not bs4Present:
irc.error("This command requires the Beautiful Soup 4 library. See"
" https://github.com/GLolol/SupyPlugins/blob/master/README.md"
"#pkginfo for instructions on how to install it.", Raise=True)
addr = 'http://packages.linuxmint.com/list.php?release=' + quote(release)
try:
fd = utils.web.getUrl(addr).decode("utf-8")
except Exception as e:
irc.error(str(e), Raise=True)
soup = BeautifulSoup(fd)
# Linux Mint puts their package lists in tables
results = soup.find_all("td")
found = OrderedDict()
query = query.lower()
exact = 'exact' in dict(opts)
for result in results:
name = result.contents[0].string # Package name
if query == name or (query in name and not exact):
# This feels like really messy code, but we have to find tags
# relative to our results.
# Ascend to find the section name (in <h2>):
section = result.parent.parent.parent.previous_sibling.\
previous_sibling.string
# Find the package version in the next <td>; for some reason we have
# to go two siblings further, as the first .next_sibling returns '\n'.
# This is mentioned briefly in Beautiful Soup 4's documentation...
version = result.next_sibling.next_sibling.string
found['%s [\x02%s\x02]' % (name, section)] = version
if found:
s = 'Found %s results: ' % len(found)
for x in found:
s += '%s \x02(%s)\x02, ' % (x, found[x])
s += 'View more at: %s' % addr
irc.reply(s)
else:
irc.error('No results found.')
mintpkg = wrap(mintpkg, ['somethingWithoutSpaces', 'somethingWithoutSpaces',
getopts({'exact':''})])
Class = PkgInfo Class = PkgInfo

View File

@ -34,7 +34,7 @@ Any specific plugin dependencies *should* also be listed.
- Generates random passwords on the fly! - Generates random passwords on the fly!
##### PkgInfo ##### PkgInfo
- Fetches package information from the websites of Debian, Ubuntu, and Arch Linux's repositories. - Fetches package information from Debian, Ubuntu, Arch Linux, and Linux Mint's repositories.
* ***Requires:*** [Beautiful Soup 4](http://www.crummy.com/software/BeautifulSoup/bs4/doc/) - install it via `pip install beautifulsoup4` or `apt-get install python-bs4`/`python3-bs4` (Debian/Ubuntu) * ***Requires:*** [Beautiful Soup 4](http://www.crummy.com/software/BeautifulSoup/bs4/doc/) - install it via `pip install beautifulsoup4` or `apt-get install python-bs4`/`python3-bs4` (Debian/Ubuntu)
##### Randomness ##### Randomness

View File

@ -28,6 +28,7 @@
### ###
import random import random
import itertools
import supybot.conf as conf import supybot.conf as conf
import supybot.utils as utils import supybot.utils as utils
@ -91,6 +92,29 @@ class SupyMisc(callbacks.Plugin):
irc.reply(random.randrange(start, stop, step)) irc.reply(random.randrange(start, stop, step))
randrange = wrap(randrange, ['int', 'int', additional('int')]) randrange = wrap(randrange, ['int', 'int', additional('int')])
def mreplace(self, irc, msg, args, bad, good, text):
"""<bad substring1>,[<bad substring2>],... <good substring1,[<good substring2>],...> <text>
Replaces all instances of <bad substringX> with <good substringX> in <text> (from left to right).
Essentially an alternative for Supybot's format.translate, but with support for substrings
of different lengths."""
if len(good) != len(bad):
irc.error("<bad substrings> must be the same length as <good substrings>", Raise=True)
for pair in itertools.izip(bad, good):
text = text.replace(pair[0], pair[1])
irc.reply(text)
mreplace = wrap(mreplace, [commalist('something'), commalist('something'), 'text'])
## Fill this in later, try to prevent forkbombs and stuff.
# def permutations(self, irc, msg, args, length, text):
# """[<length>] <text>
#
# Returns [<length>]-length permutations of <text>. If not specified, [<length>]
# defaults to the length of <text>."""
# s = ' '.join(''.join(p) for p in itertools.permutations(text, length or None))
# irc.reply(s)
# permutations = wrap(permutations, [additional('int'), 'text'])
### Generic informational commands (ident fetcher, channel counter, etc.) ### Generic informational commands (ident fetcher, channel counter, etc.)
def serverlist(self, irc, msg, args): def serverlist(self, irc, msg, args):