From 080dbc0e79c7a27903d449cd8f1e2309cda9a27b Mon Sep 17 00:00:00 2001 From: James Lu Date: Mon, 13 Oct 2014 18:24:39 -0700 Subject: [PATCH 1/5] Add mintpkg command for parsing Linux Mint's repositories (still needs testing) --- PkgInfo/plugin.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/PkgInfo/plugin.py b/PkgInfo/plugin.py index 6e5ba3b..1116d1c 100644 --- a/PkgInfo/plugin.py +++ b/PkgInfo/plugin.py @@ -209,6 +209,39 @@ class PkgInfo(callbacks.Plugin): irc.reply(s) pkgsearch = wrap(pkgsearch, ['somethingWithoutSpaces', 'somethingWithoutSpaces']) + def mintpkg(self, irc, msg, args, release, query): + """ + + Looks up 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) + results = soup.find_all("td") + found = {} + for result in results: + name = result.contents[0].string + if query == name: + self.log.info(str(result.contents)) + version, pkg = result.next_sibling.next_sibling.string, name + found[pkg] = version + self.log.info(str(found)) + 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']) + Class = PkgInfo From 09fda414d45b329b2db7d498f21bba24a2f24f73 Mon Sep 17 00:00:00 2001 From: GLolol Date: Mon, 13 Oct 2014 19:24:31 -0700 Subject: [PATCH 2/5] PkgInfo: introduce 'mintpkg' properly - Support multiple package versions (in different sections) - Add --exact option, with glob searching used by default - Update README to reflect this --- PkgInfo/README.md | 8 +++++--- PkgInfo/plugin.py | 30 ++++++++++++++++++++---------- README.md | 2 +- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/PkgInfo/README.md b/PkgInfo/README.md index 084fe9c..191c619 100644 --- a/PkgInfo/README.md +++ b/PkgInfo/README.md @@ -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: -- For Debian and Ubuntu, Debian's [madison.php](//qa.debian.org/madison.php) (for 'vlist') -- 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) \ No newline at end of file +- 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) + +Everything else is parsed as HTML using the Beautiful Soup 4 library. diff --git a/PkgInfo/plugin.py b/PkgInfo/plugin.py index 1116d1c..11edd5b 100644 --- a/PkgInfo/plugin.py +++ b/PkgInfo/plugin.py @@ -209,8 +209,8 @@ class PkgInfo(callbacks.Plugin): irc.reply(s) pkgsearch = wrap(pkgsearch, ['somethingWithoutSpaces', 'somethingWithoutSpaces']) - def mintpkg(self, irc, msg, args, release, query): - """ + def mintpkg(self, irc, msg, args, release, query, opts): + """ [--exact] Looks up in Linux Mint's repositories.""" if not bs4Present: @@ -223,15 +223,24 @@ class PkgInfo(callbacks.Plugin): 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 = {} + found = OrderedDict() + query = query.lower() + exact = 'exact' in dict(opts) for result in results: - name = result.contents[0].string - if query == name: - self.log.info(str(result.contents)) - version, pkg = result.next_sibling.next_sibling.string, name - found[pkg] = version - self.log.info(str(found)) + 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

): + section = result.parent.parent.parent.previous_sibling.\ + previous_sibling.string + # Find the package version in the next ; 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: @@ -240,7 +249,8 @@ class PkgInfo(callbacks.Plugin): irc.reply(s) else: irc.error('No results found.') - mintpkg = wrap(mintpkg, ['somethingWithoutSpaces', 'somethingWithoutSpaces']) + mintpkg = wrap(mintpkg, ['somethingWithoutSpaces', 'somethingWithoutSpaces', + getopts({'exact':''})]) Class = PkgInfo diff --git a/README.md b/README.md index a02b192..16e11cc 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Any specific plugin dependencies *should* also be listed. - Generates random passwords on the fly! ##### 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) ##### Randomness From e237bfcfd0c8952a60eaefa0718069109a7f3eed Mon Sep 17 00:00:00 2001 From: GLolol Date: Tue, 14 Oct 2014 10:50:15 -0700 Subject: [PATCH 3/5] PkgInfo: use HTTPS when available --- PkgInfo/plugin.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/PkgInfo/plugin.py b/PkgInfo/plugin.py index 11edd5b..be65522 100644 --- a/PkgInfo/plugin.py +++ b/PkgInfo/plugin.py @@ -68,12 +68,12 @@ class PkgInfo(callbacks.Plugin): self.__parent = super(PkgInfo, self) self.__parent.__init__(irc) self.addrs = {'ubuntu':'http://packages.ubuntu.com/', - 'debian':"http://packages.debian.org/"} + 'debian':"https://packages.debian.org/"} def MadisonParse(self, pkg, dist, codenames='', suite=''): arch = ','.join(self.registryValue("archs")) 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() fd = utils.web.getUrlFd(url) for line in fd.readlines(): @@ -143,7 +143,7 @@ class PkgInfo(callbacks.Plugin): Looks up in the Arch Linux package repositories. 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): fd = utils.web.getUrl(baseurl + urlencode({'name':pkg})) else: From 2b6e1cd0346b0a4ad7973331376210d9fc4df7a8 Mon Sep 17 00:00:00 2001 From: GLolol Date: Tue, 14 Oct 2014 23:07:51 -0700 Subject: [PATCH 4/5] SupyMisc: add mreplace --- SupyMisc/plugin.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/SupyMisc/plugin.py b/SupyMisc/plugin.py index 7321882..48f823e 100644 --- a/SupyMisc/plugin.py +++ b/SupyMisc/plugin.py @@ -28,6 +28,7 @@ ### import random +import itertools import supybot.conf as conf import supybot.utils as utils @@ -91,6 +92,29 @@ class SupyMisc(callbacks.Plugin): irc.reply(random.randrange(start, stop, step)) randrange = wrap(randrange, ['int', 'int', additional('int')]) + def mreplace(self, irc, msg, args, bad, good, text): + """,[],... ],...> + + Replaces all instances of with in (from left to right). + Effectively an alternative for Supybot's filter.translate, but with support for substrings + of different lengths.""" + if len(good) != len(bad): + irc.error(" must be the same length as ", 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): +# """[] +# +# Returns []-length permutations of . If not specified, [] +# defaults to the length of .""" +# 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.) def serverlist(self, irc, msg, args): From e573cb95afb0bf315ebd2383cbdda3877813c537 Mon Sep 17 00:00:00 2001 From: GLolol Date: Tue, 14 Oct 2014 23:13:27 -0700 Subject: [PATCH 5/5] SupyMisc: I shouldn't be typing out docstrings at 11PM, none of them make sense :( --- SupyMisc/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SupyMisc/plugin.py b/SupyMisc/plugin.py index 48f823e..708542b 100644 --- a/SupyMisc/plugin.py +++ b/SupyMisc/plugin.py @@ -96,7 +96,7 @@ class SupyMisc(callbacks.Plugin): """,[],... ],...> Replaces all instances of with in (from left to right). - Effectively an alternative for Supybot's filter.translate, but with support for substrings + Essentially an alternative for Supybot's format.translate, but with support for substrings of different lengths.""" if len(good) != len(bad): irc.error(" must be the same length as ", Raise=True)