commit 562f8f2cc63d467358da8ee9fb6c3aca2d141cc7 Author: WFG Date: Wed Aug 21 20:08:36 2024 +0000 first commit diff --git a/README.txt b/README.txt new file mode 100755 index 0000000..e761d98 --- /dev/null +++ b/README.txt @@ -0,0 +1,2 @@ +This plugin contains random, vaguely WFG-related commands of questionable +utility. diff --git a/__init__.py b/__init__.py new file mode 100755 index 0000000..05503a5 --- /dev/null +++ b/__init__.py @@ -0,0 +1,68 @@ +### +# Copyright (c) 2014, scythetwirler +# 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. + +### + +""" +Random, vaguely WFG-related commands of questionable utility. +""" + +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__ = "0.1" + +# XXX Replace this with an appropriate author or supybot.Author instance. +__author__ = supybot.authors.unknown + +# 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__ = '' # 'http://supybot.com/Members/yourname/Deploy/download' + +from . import config +from . import plugin +from imp import reload + +reload(config) # In case we're being reloaded. +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/__pycache__/__init__.cpython-35.pyc b/__pycache__/__init__.cpython-35.pyc new file mode 100755 index 0000000..a89bddf Binary files /dev/null and b/__pycache__/__init__.cpython-35.pyc differ diff --git a/__pycache__/__init__.cpython-39.pyc b/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000..6c90cbe Binary files /dev/null and b/__pycache__/__init__.cpython-39.pyc differ diff --git a/__pycache__/config.cpython-39.pyc b/__pycache__/config.cpython-39.pyc new file mode 100644 index 0000000..c95e244 Binary files /dev/null and b/__pycache__/config.cpython-39.pyc differ diff --git a/__pycache__/plugin.cpython-39.pyc b/__pycache__/plugin.cpython-39.pyc new file mode 100644 index 0000000..e4d1ba7 Binary files /dev/null and b/__pycache__/plugin.cpython-39.pyc differ diff --git a/config.py b/config.py new file mode 100755 index 0000000..2403daf --- /dev/null +++ b/config.py @@ -0,0 +1,60 @@ +### +# Copyright (c) 2014, scythetwirler +# Copyright (c) 2024, Stanislas Daniel Claude Dolcini +# 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('wfg') +except: + # Placeholder that allows to run the plugin on a bot + # without the i18n module + _ = lambda x: x + +def configure(advanced): + + from supybot.questions import expect, anything, something, yn + conf.registerPlugin('wfg', True) + + wfg.ticketUrl.setValue( + something("Specify the URL of the ticketing system instance.", default="https://trac.wildfiregames.com/")) + + wfg.channels.setValue( + anything("On which irc channels the bot should answer to #. If empty, prints on each joined channel.", default="", acceptEmpty=True)) + +wfg = conf.registerPlugin('wfg') + +conf.registerGlobalValue(wfg, 'ticketUrl', + registry.String("", _("URL of a ticketing system instance."))) + +conf.registerGlobalValue(wfg, 'channels', + registry.SpaceSeparatedListOfStrings("", _("On which irc channels the bot should answer to #. If empty, prints on each joined channel."))) + diff --git a/plugin.py b/plugin.py new file mode 100755 index 0000000..f241d4f --- /dev/null +++ b/plugin.py @@ -0,0 +1,95 @@ +### +# Copyright (c) 2014, scythetwirler +# Copyright (c) 2024, Stanislas Daniel Claude Dolcini +# 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 urllib.request +from html.parser import HTMLParser +import supybot.utils as utils +import supybot.plugins as plugins +import supybot.ircutils as ircutils +import supybot.callbacks as callbacks +import supybot.conf as conf +from supybot import ircmsgs + +class TitleParser(HTMLParser): + def __init__(self): + super().__init__() + self.in_title = False + self.title = None + + def handle_starttag(self, tag, attrs): + if tag.lower() == "title": + self.in_title = True + + def handle_endtag(self, tag): + if tag.lower() == "title": + self.in_title = False + + def handle_data(self, data): + if self.in_title: + self.title = data.strip() + +class wfg(callbacks.Plugin): + """This plugin contains random, vaguely WFG-related commands of questionable utility.""" + def __init__(self, irc): + self.__parent = super(wfg, self) + self.__parent.__init__(irc) + + def doPrivmsg(self, irc, msg): + nick = msg.nick + channel = msg.args[0] + payload = msg.args[1] + + channels = self.registryValue('channels') + if channels and channel not in channels: + return + matchobj = re.search(r'#\d+', payload) + if matchobj is not None: + ticket_number = matchobj.group(0).lstrip('#') + ticket_url = self.registryValue('ticketUrl') + url = f'{ticket_url.rstrip("/")}/ticket/{ticket_number}' + + # Fetch the title of the ticket page + try: + with urllib.request.urlopen(url) as response: + html = response.read().decode('utf-8') + parser = TitleParser() + parser.feed(html) + title = parser.title if parser.title else "No title found" + # Clean up the title if necessary + title = re.sub(r'\s*–\s*Wildfire Games\s*$', '', title) + except Exception as e: + return + + response = f'{title} – {url}' + irc.queueMsg(ircmsgs.privmsg(channel, response)) + +Class = wfg diff --git a/test.py b/test.py new file mode 100755 index 0000000..ad1ac94 --- /dev/null +++ b/test.py @@ -0,0 +1,37 @@ +### +# Copyright (c) 2014, scythetwirler +# 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 WFGTestCase(PluginTestCase): + plugins = ('wfg',) + + +# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79: