diff --git a/FML/README.md b/FML/README.md deleted file mode 100644 index 4d0f9e3..0000000 --- a/FML/README.md +++ /dev/null @@ -1 +0,0 @@ -Implements an **`fml`** command, displaying entries from [fmylife.com](https://www.fmylife.com/). diff --git a/FML/__init__.py b/FML/__init__.py deleted file mode 100644 index 76a449c..0000000 --- a/FML/__init__.py +++ /dev/null @@ -1,68 +0,0 @@ -### -# Copyright (c) 2014-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. - -### - -""" -FML: Displays entries from fmylife.com. -""" - -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__ = "2021.08.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/FML/config.py b/FML/config.py deleted file mode 100644 index 7d2ea43..0000000 --- a/FML/config.py +++ /dev/null @@ -1,55 +0,0 @@ -### -# Copyright (c) 2014-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 - _ = PluginInternationalization('FML') -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('FML', True) - - -FML = conf.registerPlugin('FML') -conf.registerChannelValue(FML, 'showInfo', - registry.Boolean(True, _("""Determines whether the bot should show more info (ID, category, and URL) in FML posts."""))) - -# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79: diff --git a/FML/local/__init__.py b/FML/local/__init__.py deleted file mode 100644 index e86e97b..0000000 --- a/FML/local/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# Stub so local is a module, used for third-party modules diff --git a/FML/plugin.py b/FML/plugin.py deleted file mode 100644 index 2e91102..0000000 --- a/FML/plugin.py +++ /dev/null @@ -1,128 +0,0 @@ -### -# Copyright (c) 2014-2018, 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 collections - -from supybot import utils, plugins, ircutils, callbacks, log -from supybot.commands import * -try: - from supybot.i18n import PluginInternationalization - _ = PluginInternationalization('FML') -except ImportError: - # Placeholder that allows to run the plugin on a bot - # without the i18n module - _ = lambda x: x - -from bs4 import BeautifulSoup - -class FML(callbacks.Plugin): - """Displays entries from fmylife.com.""" - threaded = True - - URL_RANDOM = 'https://www.fmylife.com/random' - URL_ARTICLE = 'https://www.fmylife.com/article/-_%s.html' # subst in the ID - cached_results = collections.deque() - - @staticmethod - def _parse_panel(panel, fml_id=None): - """Parses a FML entry panel for data. Returns a (fml_id, text, num_upvotes, num_downvotes) tuple.""" - if panel: - content = panel.find(class_='article-link') - log.debug("FML: parsing panel %s", panel) - log.debug("FML: parsing content %s", content) - - if not content: - return - text = content.text.strip() - if not text.endswith(' FML'): # Ignore ads, promos, previews - return - - # If not given, extract the FML ID from the link - if fml_id is None and content.name == 'a': - link = content['href'] - fml_id = link.rsplit('_', 1)[-1].split('.', 1)[0] - - vote_counts = panel.find_all('div', class_='vote-count') - upvotes = vote_counts[0].text.strip() - downvotes = vote_counts[1].text.strip() - - data = (fml_id, text, upvotes, downvotes) - return data - - def _get_random_entries(self): - """Fetches and caches random FML entries. Returns the amount of entries retrieved.""" - html = utils.web.getUrl(self.URL_RANDOM) - soup = BeautifulSoup(html) - - results_count = 0 - for panel in soup.find_all('div', class_='article-contents'): - data = self._parse_panel(panel) - if data: - self.log.debug('FML: got entry: %s', str(data)) - self.cached_results.append(data) - results_count += 1 - - self.log.debug('FML: got total of %s results, cache size: %s', results_count, - len(self.cached_results)) - return results_count - - def fml(self, irc, msg, args, query): - """[] - - Displays an entry from fmylife.com. If is not given, fetch a random entry from the API.""" - if query: # Explicit ID given - html = utils.web.getUrl(self.URL_ARTICLE % query) - soup = BeautifulSoup(html) - panel = soup.find('div', class_='article-contents') - data = self._parse_panel(panel, fml_id=query) - else: # Random search - if not len(self.cached_results): - if not self._get_random_entries(): - irc.error("Could not fetch new FML entries - try again later.", Raise=True) - data = self.cached_results.popleft() - - if not data: - irc.error(_("Entry not found or error processing data."), Raise=True) - fml_id, text, num_upvotes, num_downvotes = data - - votes = ircutils.bold("[Agreed: %s / Deserved: %s]" % (num_upvotes, num_downvotes)) - if self.registryValue("showInfo", msg.args[0]): - url = self.URL_ARTICLE % fml_id - s = format('\x02#%i\x02: %s - %s %u', fml_id, text, votes, url) - else: - s = format('%s - %s', text, votes) - - irc.reply(s) - - fml = wrap(fml, [additional('positiveInt')]) - -Class = FML - - -# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: diff --git a/FML/test.py b/FML/test.py deleted file mode 100644 index 0bd251d..0000000 --- a/FML/test.py +++ /dev/null @@ -1,44 +0,0 @@ -### -# Copyright (c) 2014-2018, 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 FMLTestCase(PluginTestCase): - plugins = ('FML',) - - @unittest.skipUnless(network, "Network-based tests have been disabled via " - "--no-network") - def testFML(self): - self.assertNotError('fml') - self.assertNotError('fml 165130') - self.assertError('fml 1') # This one doesn't exist - -# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79: diff --git a/README.md b/README.md index 951f2ca..36a97d0 100644 --- a/README.md +++ b/README.md @@ -34,10 +34,6 @@ Most of these plugins also have their own READMEs in their folders; you can usua ##### AQI - Retrieves [air quality index](https://en.wikipedia.org/wiki/Air_quality_index) info from the [World Air Quality Index project](https://aqicn.org). -##### FML -- Displays random entries from fmylife.com. - - **Requires:** [Beautiful Soup 4](http://www.crummy.com/software/BeautifulSoup/bs4/doc/) - ##### LastFM - LastFM plugin, forked from [krf/supybot-lastfm](https://github.com/krf/supybot-lastfm).