diff --git a/MCInfo/README.md b/MCInfo/README.md deleted file mode 100644 index cc3fdbc..0000000 --- a/MCInfo/README.md +++ /dev/null @@ -1 +0,0 @@ -Fetches crafting recipes and other interesting information from the [Minecraft Wiki](http://minecraft.gamepedia.com). diff --git a/MCInfo/__init__.py b/MCInfo/__init__.py deleted file mode 100644 index 1b99691..0000000 --- a/MCInfo/__init__.py +++ /dev/null @@ -1,68 +0,0 @@ -### -# Copyright (c) 2016, 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. - -### - -""" -MCInfo: Fetches crafting recipes and other interesting information from the Minecraft Wiki. -""" - -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__ = "2022.02.01+git" - -__author__ = getattr(supybot.authors, 'jlu', - supybot.Author('James Lu', 'jlu5', 'james@overdrivenetworks.com')) - -# This is a dictionary mapping supybot.Author instances to lists of -# contributions. -__contributors__ = {} - -# This is a url where the most recent plugin package can be downloaded. -__url__ = 'https://github.com/jlu5/SupyPlugins/' - -from . import config -from . import plugin -from imp import reload -# In case we're being reloaded. -reload(config) -reload(plugin) -# 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: diff --git a/MCInfo/config.py b/MCInfo/config.py deleted file mode 100644 index 6fdcc26..0000000 --- a/MCInfo/config.py +++ /dev/null @@ -1,57 +0,0 @@ -### -# Copyright (c) 2016, 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 - _ = PluginInternationalization('MCInfo') -except: - # Placeholder that allows to run the plugin on a bot - # without the i18n module - _ = 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 themself 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('MCInfo', True) - - -MCInfo = conf.registerPlugin('MCInfo') -# This is where your configuration variables (if any) should go. For example: -# conf.registerGlobalValue(MCInfo, 'someConfigVariableName', -# registry.Boolean(False, _("""Help for someConfigVariableName."""))) - - -# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79: diff --git a/MCInfo/local/__init__.py b/MCInfo/local/__init__.py deleted file mode 100644 index e86e97b..0000000 --- a/MCInfo/local/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# Stub so local is a module, used for third-party modules diff --git a/MCInfo/plugin.py b/MCInfo/plugin.py deleted file mode 100644 index 33e126e..0000000 --- a/MCInfo/plugin.py +++ /dev/null @@ -1,240 +0,0 @@ -### -# Copyright (c) 2016, 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 wrap -import supybot.plugins as plugins -import supybot.ircutils as ircutils -import supybot.callbacks as callbacks -try: - from supybot.i18n import PluginInternationalization - _ = PluginInternationalization('MCInfo') -except ImportError: - # Placeholder that allows to run the plugin on a bot - # without the i18n module - _ = lambda x: x - -import sys - -if sys.version_info[0] >= 3: - from urllib.parse import quote -else: - from urllib import quote - -from bs4 import BeautifulSoup - -mcwiki_url = 'http://minecraft.gamepedia.com' - -def format_text(text): - text = text.replace('\xa0', '') - text = utils.str.normalizeWhitespace(text) - text = text.strip() - return text - -class MCInfo(callbacks.Plugin): - """Fetches crafting recipes and other interesting information from the Minecraft Wiki.""" - threaded = True - - @wrap(['text']) - def mcwiki(self, irc, msg, args, item): - """ - Gets information from the Minecraft Wiki. This requires the Wikifetch plugin to be loaded. - """ - wf = irc.getCallback("Wikifetch") - - if wf: - # Use the Wikifetch plugin in this repository to lookup the information on the - # item, tool, or thing given. - text = wf._wiki(irc, msg, item, mcwiki_url) - if _('may refer to') in text: - irc.reply('%s seems to be a disambiguation page.' % text.split()[-1]) - else: - irc.reply(text) - else: - irc.error("This command requires the Wikifetch plugin to be loaded.", Raise=True) - - def get_page(self, irc, item): - """Returns the wiki page for the given item.""" - url = '%s/%s' % (mcwiki_url, quote(item)) - self.log.debug("MCInfo: using url %s", url) - - try: - article = utils.web.getUrl(url) - except utils.web.Error as e: - if '404' in str(e): - irc.error("Unknown item.", Raise=True) - irc.error(e, Raise=True) - - soup = BeautifulSoup(article) - return soup - - @wrap(['text']) - def craft(self, irc, msg, args, item): - """ - - Attempts to look up crafting information from the Minecraft wiki. - """ - - soup = self.get_page(irc, item) - - # Find the "Crafting table" displayed in the Wiki page showing how to craft the item. - crafting_table = soup.find('table', attrs={"data-description": 'Crafting recipes'}) - if not crafting_table: - irc.error("No crafting information found.", Raise=True) - - for tag in crafting_table.previous_siblings: - # We only want the instructions on how to craft the item, not the items crafted WITH it. - # TODO: maybe this behavior could be a different command? - if tag.name == 'h3': - t = tag.contents[0].get_text().strip() - if t == 'Crafting ingredient': - irc.error("The item '%s' cannot be crafted." % item, Raise=True) - - # Get the first crafting result. TODO: optionally show all recipes if there are more than one. - crafting_data = crafting_table.find_all('tr')[1] - - # Shows the text of the ingredients used to craft (e.g. "Glass + Any dye") - ingredients = format_text(crafting_data.td.get_text()) - - recipe = [] - - # This tracks how long the longest item name is. Used for formatting the crafting table on - # IRC with the right dimensions. - maxitemlength = 0 - - # Now, parse the layout of the 3x3 crafting grid the wiki shows for items. - for rowdata in crafting_data.find_all('span', class_='mcui-row'): - rowitems = [] - # Iterate over the rows of the crafting grid, and then the items in each. - for itemslot in rowdata.children: - - itemlink = itemslot.a - if itemlink: - # Item exists. Get the name of the item using the caption of its wiki page link. - itemname = itemlink.get('title') - - # Replace spaces with hyphens in the display to make the display monospace. - #itemname = itemname.replace(' ', '-') - - # Update the existing max item length if the length of the current one is - # greater. - if len(itemname) > maxitemlength: - maxitemlength = len(itemname) - - rowitems.append(itemname) - elif not itemslot.find('invslot-item'): - # Empty square. - rowitems.append('') - if rowitems: - recipe.append(rowitems) - - irc.reply("Recipe for %s uses: %s" % (ircutils.bold(item), ircutils.bold(ingredients))) - for row in filter(any, recipe): # Only output rows that have filled squares. - # For each item, center its name based on the length of the longest item name in the - # recipe. This gives the grid a more monospace-y feel. - items = [s.center(maxitemlength, '-') for s in row] - irc.reply('|%s|' % '|'.join(items)) - - @wrap(['text']) - def smelt(self, irc, msg, args, item): - """ - - Attempts to look up smelting recipes from the Minecraft wiki. - """ - - soup = self.get_page(irc, item) - - # Find the "smelting" table displayed in the Wiki page. - smelting_tables = soup.find_all('table', attrs={"data-description": 'Smelting recipes'}) - if not smelting_tables: - irc.error("No smelting information found.", Raise=True) - - irc.reply("Smelting recipes involving %s:" % ircutils.bold(item)) - - for table in smelting_tables: - - # Get the first smelting result. - smelt_data = table.find_all('tr')[1] - - # Show the resulting item and the ingredients needed to smelt it. - ingredients = format_text(smelt_data.td.get_text()) - try: - result = format_text(smelt_data.th.get_text()) - except AttributeError: - # If the text of the result item isn't explicitly shown, dig - # deeper to extract the item name from the smelting table UI. - smelting_ui = smelt_data.find_all('td')[1].div.span - - output = smelting_ui.find('span', class_='mcui-output') - - result = output.find('span', class_='sprite') - result = result.get('title') - - irc.reply("%s: %s" % (ircutils.bold(result), ingredients)) - - @wrap(['text']) - def recipes(self, irc, msg, args, item): - """ - - Returns Minecraft crafting recipes using the given item. - """ - - soup = self.get_page(irc, item) - - # First, look for the "Crafting ingredient" header (usually under a - # section called "Usage"). Only here will we find the recipes for each - # item. - header = '' - for header in soup.find_all('h3'): - if header.span and header.span.get_text().strip().lower() == 'crafting ingredient': - break - else: - irc.error("No recipes found.", Raise=True) - - for tag in header.next_siblings: - # Only look at crafting table UIs after this header. - if tag.name == 'table' and tag.get("data-description").lower() == 'crafting recipes': - recipes = [] - - # Iterate over all the recipes shown and get their names. - for crafting_data in tag.find_all('tr')[1:]: - recipes.append(format_text(crafting_data.th.get_text())) - - # After we've found these results, we can stop looking for - # crafting table UIs. - break - - out_s = format('Recipes using %s include: %L', ircutils.bold(item), sorted(recipes)) - irc.reply(out_s) - -Class = MCInfo - - -# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: diff --git a/MCInfo/setup.py b/MCInfo/setup.py deleted file mode 100644 index 2e0085f..0000000 --- a/MCInfo/setup.py +++ /dev/null @@ -1,9 +0,0 @@ - -from supybot.setup import plugin_setup - -plugin_setup( - 'MCInfo', - install_requires=[ - 'bs4', - ], -) diff --git a/MCInfo/test.py b/MCInfo/test.py deleted file mode 100644 index e97accd..0000000 --- a/MCInfo/test.py +++ /dev/null @@ -1,38 +0,0 @@ -### -# Copyright (c) 2016, 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 MCInfoTestCase(PluginTestCase): - plugins = ('MCInfo',) - - -# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79: diff --git a/README.md b/README.md index 87e2b23..1cfebc7 100644 --- a/README.md +++ b/README.md @@ -37,10 +37,6 @@ Most of these plugins also have their own READMEs in their folders; you can usua ### LastFM - LastFM plugin, forked from [krf/supybot-lastfm](https://github.com/krf/supybot-lastfm). -### MCInfo -- Fetches information from [minecraft.gamepedia.com](https://minecraft.gamepedia.com/). - - **Requires:** [Beautiful Soup 4](http://www.crummy.com/software/BeautifulSoup/bs4/doc/) - ### [NoTrigger](NoTrigger/README.md) - Anti-abuse script; prevents the bot from triggering other bots by modifying its output slightly. For more information, see [NoTrigger/README.md](NoTrigger/README.md).