This commit is contained in:
James Lu 2015-05-17 21:43:34 -07:00
parent e5f117db54
commit f6118edd74
10 changed files with 663 additions and 0 deletions

View File

@ -75,3 +75,6 @@ Most of these plugins also have their own READMEs in their folders; you can usua
##### [Weather](Weather/README.md) ##### [Weather](Weather/README.md)
- My fork of [reticulatingspline's Weather](https://github.com/reticulatingspline/Weather) plugin. [Source](https://github.com/GLolol/Supybot-Weather) - My fork of [reticulatingspline's Weather](https://github.com/reticulatingspline/Weather) plugin. [Source](https://github.com/GLolol/Supybot-Weather)
##### Wikifetch
- Fork of [ProgVal's Wikipedia plugin](https://github.com/ProgVal/Supybot-plugins), with support for other wikis (via a `--site` option) and other improvements.

20
Wikifetch/README.md Normal file
View File

@ -0,0 +1,20 @@
Grabs data from Wikipedia and other MediaWiki-powered sites.
## Usage
```
<GLolol> `wiki apple
<Atlas> The apple tree (Malus domestica) is a deciduous tree in the rose family best known for its sweet, pomaceous fruit, the apple. It is cultivated worldwide as a fruit tree, and is the most widely grown species in the genus Malus. The tree originated in Central Asia, where its wild ancestor, Malus sieversii, is still found today. Apples have been grown for thousands of years in Asia and Europe, and were (1 more message)
```
You can also add other sites using the `--site` option:
```
<GLolol> `wiki --site wiki.archlinux.org/index.php Bash
<Atlas> Bash (Bourne-again Shell) is a command-line shell/programming language by the GNU Project. Its name is a homaging reference to its predecessor: the long-deprecated Bourne shell. Bash can be run on most UNIX-like operating systems, including GNU/Linux. Retrieved from <https://wiki.archlinux.org/index.php?title=Bash>
```
```
<GLolol> `wiki --site community.wikia.com Help:Wikitext
<Atlas> Wikitext is the main markup language used to format content on wikias. It can be used to add photos, tables, bold styles, links, and other visual changes. Retrieved from <http://community.wikia.com/wiki/Help:Wikitext>
```

75
Wikifetch/__init__.py Normal file
View File

@ -0,0 +1,75 @@
###
# Copyright (c) 2010, quantumlemur
# Copyright (c) 2015, 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.
###
"""
Grabs data from Wikipedia and other MediaWiki-powered sites.
"""
import supybot
import supybot.world as world
# Use this for the version of this plugin. You may wish to put a CVS keyword
# in here if you're keeping the plugin in CVS or some similar system.
__version__ = ""
# XXX Replace this with an appropriate author or supybot.Author instance.
__author__ = supybot.Author('quantumlemur', 'quantumlemur',
'quantumlemur@users.sourceforge.net')
# This is a dictionary mapping supybot.Author instances to lists of
# contributions.
if not hasattr(supybot.authors, 'progval'):
supybot.authors.progval = supybot.Author('Valentin Lorentz', 'ProgVal',
'progval@gmail.com')
__contributors__ = {supybot.authors.progval: ['enhance configurability',
'many bug fixes',
'internationalization'],
supybot.Author('James Lu', 'GLolol', 'glolol1@hotmail.com'):
['formatting updates',
'multiple wiki support']}
__url__ = 'https://github.com/GLolol/SupyPlugins'
from . import config
from . import plugin
from imp import reload
reload(plugin) # In case we're being reloaded.
# Add more reloads here if you add third-party modules and want them to be
# reloaded when this plugin is reloaded. Don't forget to import them as well!
if world.testing:
from . import test
Class = plugin.Class
configure = config.configure
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:

62
Wikifetch/config.py Normal file
View File

@ -0,0 +1,62 @@
###
# Copyright (c) 2010, quantumlemur
# Copyright (c) 2011, Valentin Lorentz
# Copyright (c) 2015, 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.conf as conf
import supybot.registry as registry
try:
from supybot.i18n import PluginInternationalization
from supybot.i18n import internationalizeDocstring
_ = PluginInternationalization('Wikifetch')
except:
# This are useless functions that's allow to run the plugin on a bot
# without the i18n plugin
_ = lambda x:x
internationalizeDocstring = lambda x:x
def configure(advanced):
# This will be called by supybot to configure this module. advanced is
# a bool that specifies whether the user identified himself as an advanced
# user or not. You should effect your configuration by manipulating the
# registry as appropriate.
from supybot.questions import expect, anything, something, yn
conf.registerPlugin('Wikifetch', True)
Wikifetch = conf.registerPlugin('Wikifetch')
conf.registerChannelValue(Wikifetch, 'url',
registry.String(_('en.wikipedia.org'), _("""Default URL of the
website to pull from.""")))
conf.registerChannelValue(Wikifetch, 'showRedirects',
registry.Boolean(True, _("""Determines whether redirect paths will
be shown in the output.""")))
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:

View File

@ -0,0 +1 @@
# Stub so local is a module, used for third-party modules

76
Wikifetch/locales/fr.po Normal file
View File

@ -0,0 +1,76 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: Supybot-fr\n"
"POT-Creation-Date: 2011-03-02 11:00+CET\n"
"PO-Revision-Date: 2011-03-02 11:06+0100\n"
"Last-Translator: James Lu <glolol1@hotmail.com>\n"
"Language-Team: ProgVal <progval@gmail.com>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: pygettext.py 1.5\n"
"X-Poedit-Language: Français\n"
"X-Poedit-Country: France\n"
#: config.py:59
msgid ""
"URL of the website from\n"
" where you want to pull pages (usually: your language's\n"
" wikipedia)"
msgstr "URL du site web d'om vous voulez récuper les page (généralement : le Wikipedia de votre langue."
#: config.py:59
msgid "en.wikipedia.org"
msgstr "fr.wikipedia.org"
#: plugin.py:56
msgid ""
"Add the help for \"@plugin help Wikipedia\" here\n"
" This should describe *how* to use this plugin."
msgstr ""
#: plugin.py:63
msgid ""
"<search term>\n"
"\n"
" Returns the first paragraph of a Wikipedia article"
msgstr ""
"<terme recherché>\n"
"\n"
"Retourne le premier paragraphe d'un article de Wikipedia."
#: plugin.py:79
msgid "I didn't find anything for \"%s\". Did you mean \"%s\"? "
msgstr "Je ne peux rien trouver pour \"%s\". Vouliez-vous dire \"%s\" ?"
#: plugin.py:91
msgid "I didn't find anything for \"%s\", but here's the result for \"%s\": "
msgstr "Je ne peux rien trouver pour \"%s\", mais voici le résultat de \"%s\" : "
#: plugin.py:101
msgid "Redirected from"
msgstr "Redirigé de"
#: plugin.py:118
msgid "%s is a disambiguation page. Possible results are: %s"
msgstr "%s est une page de désambiguation. Les résultats possibles son : %s"
#: plugin.py:121
msgid "This article is about the year [\\d]*\\. For the [a-zA-Z ]* [\\d]*, see"
msgstr "Cette page concerne l'année"
#: plugin.py:123
msgid "\"%s\" is a page full of events that happened in that year. If you were looking for information about the number itself, try searching for \"%s_(number)\", but don't expect anything useful..."
msgstr "\"%s\" est une page pleine d'évènement qui se sont produits cette année. Si vous recherches des informations à propos du nombre lui-même, essayez de rechercher \"%s_(nombre)\", mais ne vous attendez pas à quelque chose d'utile..."
#: plugin.py:131
msgid "Not found, or page malformed."
msgstr "Non trouvé, ou page mal formée."
#: plugin.py:168
msgid "Retrieved from"
msgstr "Recu de"

74
Wikifetch/locales/it.po Normal file
View File

@ -0,0 +1,74 @@
msgid ""
msgstr ""
"Project-Id-Version: Supybot-fr\n"
"POT-Creation-Date: 2011-02-26 09:49+CET\n"
"PO-Revision-Date: 2011-07-29 17:43+0200\n"
"Last-Translator: James Lu <glolol1@hotmail.com>\n"
"Language-Team: Italian <skizzhg@gmx.com>\n"
"Language: it\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: config.py:59
msgid ""
"URL of the website from\n"
" where you want to pull pages (usually: your language's\n"
" wikipedia)"
msgstr ""
"URL del sito web da cui recuperare le pagine (solitamente wikipedia nella tua lingua)."
#: config.py:59
msgid "en.wikipedia.org"
msgstr "it.wikipedia.org"
#: plugin.py:56
#, docstring
msgid ""
"Add the help for \"@plugin help Wikipedia\" here\n"
" This should describe *how* to use this plugin."
msgstr ""
#: plugin.py:63
#, docstring
msgid ""
"<search term>\n"
"\n"
" Returns the first paragraph of a Wikipedia article"
msgstr ""
"<termine di ricerca>\n"
"\n"
" Restituisce il primo paragrafo di un articolo di Wikipedia."
#: plugin.py:79
msgid "I didn't find anything for \"%s\". Did you mean \"%s\"? "
msgstr "Non trovo nulla per \"%s\"; intendevi \"%s\"? "
#: plugin.py:91
msgid "I didn't find anything for \"%s\", but here's the result for \"%s\": "
msgstr "Non trovo nulla per \"%s\", ma questi sono i risultati per \"%s\": "
#: plugin.py:101
msgid "Redirected from"
msgstr "Rediretto da"
#: plugin.py:118
msgid "%s is a disambiguation page. Possible results are: %s"
msgstr "%s è una pagina di disambiguazione; i possibili risultati sono: %s"
#: plugin.py:121
msgid "This article is about the year [\\d]*\\. For the [a-zA-Z ]* [\\d]*, see"
msgstr "Questo articolo è circa dell'anno [\\d]*\\. Per il [a-zA-Z ]* [\\d]* vedi"
#: plugin.py:123
msgid "\"%s\" is a page full of events that happened in that year. If you were looking for information about the number itself, try searching for \"%s_(number)\", but don't expect anything useful..."
msgstr "\"%s\" è una pagina piena di eventi accaduti quest'anno. Se stavi cercando informazioni sul numero prova \"%s_(numero)\", ma non aspettarti niente di utile..."
#: plugin.py:131
msgid "Not found, or page malformed."
msgstr "Non trovato, o pagina non valida."
#: plugin.py:168
msgid "Retrieved from"
msgstr "Recuperato da"

75
Wikifetch/messages.pot Normal file
View File

@ -0,0 +1,75 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2011-03-02 11:00+CET\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.5\n"
#: config.py:59
msgid ""
"URL of the website from\n"
" where you want to pull pages (usually: your language's\n"
" wikipedia)"
msgstr ""
#: config.py:59
msgid "en.wikipedia.org"
msgstr ""
#: plugin.py:56
#, docstring
msgid ""
"Add the help for \"@plugin help Wikipedia\" here\n"
" This should describe *how* to use this plugin."
msgstr ""
#: plugin.py:63
#, docstring
msgid ""
"<search term>\n"
"\n"
" Returns the first paragraph of a Wikipedia article"
msgstr ""
#: plugin.py:79
msgid "I didn't find anything for \"%s\".Did you mean \"%s\"? "
msgstr ""
#: plugin.py:91
msgid "I didn't find anything for \"%s\", but here's the result for \"%s\": "
msgstr ""
#: plugin.py:101
msgid "Redirected from"
msgstr ""
#: plugin.py:109
msgid "Retrieved from"
msgstr ""
#: plugin.py:118
msgid "%s is a disambiguation page. Possible results are: %s"
msgstr ""
#: plugin.py:121
msgid "This article is about the year [\\d]*\\. For the [a-zA-Z ]* [\\d]*, see"
msgstr ""
#: plugin.py:123
msgid "\"%s\" is a page full of events that happened in that year. If you were looking for information about the number itself, try searching for \"%s_(number)\", but don't expect anything useful..."
msgstr ""
#: plugin.py:131
msgid "Not found, or page bad formed."
msgstr ""

213
Wikifetch/plugin.py Normal file
View File

@ -0,0 +1,213 @@
###
# Copyright (c) 2010, quantumlemur
# Copyright (c) 2011, Valentin Lorentz
# Copyright (c) 2015, 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 re
import sys
import urllib
import lxml.html
from lxml import etree
import supybot.utils as utils
from supybot.commands import *
import supybot.plugins as plugins
import supybot.ircutils as ircutils
import supybot.callbacks as callbacks
try:
from supybot.i18n import PluginInternationalization
from supybot.i18n import internationalizeDocstring
_ = PluginInternationalization('Wikifetch')
except:
# This are useless functions that's allow to run the plugin on a bot
# without the i18n plugin
_ = lambda x:x
internationalizeDocstring = lambda x:x
if sys.version_info[0] >= 3:
quote_plus = urllib.parse.quote_plus
else:
quote_plus = urllib.quote_plus
class Wikifetch(callbacks.Plugin):
"""Grabs data from Wikipedia and other MediaWiki-powered sites."""
threaded = True
@internationalizeDocstring
def wiki(self, irc, msg, args, optlist, search):
"""[--site <site>] <search term>
Returns the first paragraph of a Wikipedia article."""
reply = ''
optlist = dict(optlist)
# Different instances of MediaWiki use different URLs... This tries
# to make the parser work for most sites, but still use resonable defaults
# such as filling in http:// and appending /wiki to links...
# Try using '--site lyrics.wikia.com' or '--site wiki.archlinux.org/index.php'.
if 'site' in optlist:
baseurl = optlist['site']
if 'wikia.com' in baseurl:
baseurl += '/wiki'
if not baseurl.lower().startswith(('http://', 'https://')):
baseurl = 'http://' + baseurl
else:
baseurl = 'https://%s/wiki' % self.registryValue('url', msg.args[0])
# first, we get the page
addr = '%s/Special:Search?search=%s' % \
(baseurl, quote_plus(search))
article = utils.web.getUrl(addr)
if sys.version_info[0] >= 3:
article = article.decode()
# parse the page
tree = lxml.html.document_fromstring(article)
# check if it gives a "Did you mean..." redirect
didyoumean = tree.xpath('//div[@class="searchdidyoumean"]/a'
'[@title="Special:Search"]')
if didyoumean:
redirect = didyoumean[0].text_content().strip()
if sys.version_info[0] < 3:
if isinstance(redirect, unicode):
redirect = redirect.encode('utf-8','replace')
if isinstance(search, unicode):
search = search.encode('utf-8','replace')
if self.registryValue('showRedirects', msg.args[0]):
reply += _('I didn\'t find anything for "%s". '
'Did you mean "%s"? ') % (search, redirect)
addr = "%s/%s" % (baseurl,
didyoumean[0].get('href'))
article = utils.web.getUrl(addr)
if sys.version_info[0] >= 3:
article = article.decode()
tree = lxml.html.document_fromstring(article)
search = redirect
# check if it's a page of search results (rather than an article), and
# if so, retrieve the first result
searchresults = tree.xpath('//div[@class="searchresults"]/ul/li/a')
if searchresults:
redirect = searchresults[0].text_content().strip()
if self.registryValue('showRedirects', msg.args[0]):
reply += _('I didn\'t find anything for "%s", but here\'s the '
'result for "%s": ') % (search, redirect)
addr = self.registryValue('url', msg.args[0]) + \
searchresults[0].get('href')
article = utils.web.getUrl(addr)
if sys.version_info[0] >= 3:
article = article.decode()
tree = lxml.html.document_fromstring(article)
search = redirect
# otherwise, simply return the title and whether it redirected
elif self.registryValue('showRedirects', msg.args[0]):
redirect = re.search('\(%s <a href=[^>]*>([^<]*)</a>\)' %
_('Redirected from'), article)
if redirect:
try:
redirect = tree.xpath('//span[@class="mw-redirectedfrom"]/a')[0]
redirect = redirect.text_content().strip()
title = tree.xpath('//*[@class="firstHeading"]')
title = title[0].text_content().strip()
if sys.version_info[0] < 3:
if isinstance(title, unicode):
title = title.encode('utf-8','replace')
if isinstance(redirect, unicode):
redirect = redirect.encode('utf-8','replace')
reply += '"%s" (Redirected from "%s"): ' % (title, redirect)
except IndexError:
pass
# extract the address we got it from
# We only care about formatting this if we're actually on Wikipedia
# (i.e. not using --site <site>)
try:
if 'site' not in optlist:
addr = tree.find(".//link[@rel='canonical']")
addr = addr.attrib['href']
# force serving HTTPS links
addr = 'https://' + addr.split("//")[1]
else:
addr = tree.find(".//div[@class='printfooter']/a").attrib['href']
addr = re.sub('([&?]|(amp;)?)oldid=\d+$', '', addr)
except:
pass
# check if it's a disambiguation page
disambig = tree.xpath('//table[@id="disambigbox"]') or \
tree.xpath('//table[@id="setindexbox"]')
if disambig:
disambig = tree.xpath('//div[@id="bodyContent"]/div/ul/li/a')
disambig = disambig[:5]
disambig = [item.text_content() for item in disambig]
r = utils.str.commaAndify(disambig)
reply += format(_('%u is a disambiguation page. '
'Possible results include: %s'), addr, r)
# or just as bad, a page listing events in that year
elif re.search(_('This article is about the year [\d]*\. '
'For the [a-zA-Z ]* [\d]*, see'), article):
reply += _('"%s" is a page full of events that happened in that '
'year. If you were looking for information about the '
'number itself, try searching for "%s_(number)", but '
'don\'t expect anything useful...') % (search, search)
# Catch talk pages
elif 'ns-talk' in tree.find("body").attrib['class']:
reply += format(_('This article appears to be a talk page: %u'), addr)
else:
##### etree!
p = tree.xpath("//div[@id='mw-content-text']/p[1]")
if len(p) == 0 or 'wiki/Special:Search' in addr:
if 'wikipedia:wikiproject' in addr.lower():
reply += format(_('This page appears to be a WikiProject page, '
'but it is too complex for us to parse: %u'), addr)
else:
reply += _('Not found, or page malformed.')
else:
p = p[0]
# Replace <b> tags with IRC-style bold, this has to be
# done indirectly because unescaped '\x02' is invalid in XML
for b_tag in p.xpath('//b'):
b_tag.text = "&#x02;%s&#x02;" % b_tag.text
p = p.text_content()
p = p.replace('&#x02;', '\x02')
p = p.strip()
if sys.version_info[0] < 3:
if isinstance(p, unicode):
p = p.encode('utf-8', 'replace')
if isinstance(reply, unicode):
reply = reply.encode('utf-8','replace')
reply += format('%s %s %u', p, _('Retrieved from'), addr)
reply = reply.replace('&amp;','&')
# Remove inline citations (text[1][2][3], etc.)
reply = re.sub('\[\d+\]', '', reply)
irc.reply(reply)
wiki = wrap(wiki, [getopts({'site': 'somethingWithoutSpaces'}), 'text'])
Class = Wikifetch
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

64
Wikifetch/test.py Normal file
View File

@ -0,0 +1,64 @@
###
# Copyright (c) 2010, quantumlemur
# Copyright (c) 2011, Valentin Lorentz
# Copyright (c) 2015, 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.
###
from supybot.test import *
class WikifetchTestCase(PluginTestCase):
plugins = ('Wikifetch',)
if network:
def testWiki(self):
self.assertRegexp('wiki Monty Python',
'\x02Monty Python\x02 \(sometimes known as \x02The Pythons\x02\)')
self.assertRegexp('wiki roegdfjpoepo',
'Not found, or page malformed.*')
def testDisambiguation(self):
self.assertRegexp('wiki Python', 'is a disambiguation page.*'
'Possible results include:.*?,.*?,')
self.assertRegexp('wiki Windows 3', '.*is a disambiguation page.*'
'Possible results include:.*?Windows 3.0.*?,.*?Windows 3.1x')
def testWikiRedirects(self):
# Via did you mean clause
self.assertRegexp('wiki George Washingon',
'first President of the United States')
# Via Search find-first-result snarfer
self.assertRegexp('wiki synnero',
'A \x02synchro\x02 is')
self.assertRegexp('wiki Foo', '"Foobar" \(Redirected from "Foo"\): '
'The terms \x02foobar\x02')
def testStripInlineCitations(self):
self.assertNotRegexp('wiki UNICEF', '\[\d+\]')
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79: