Compare commits

...

5 Commits

Author SHA1 Message Date
0d22b8e05b
Print links for all mentioned tickets
Up to now this plugin only printed the link for the first encountered
ticket id. With this change links for all tickets are printed instead.
2024-09-21 14:25:11 +02:00
aeaa93d82e
Use a regex to extract the page title 2024-09-21 14:25:11 +02:00
925e95e847
Don't match ticket ids embedded in words
Only match ticket ids which are a separate word or are prepended by a
special character to avoid false-positives matches.
2024-09-21 14:24:31 +02:00
3d38561875
Simplify code 2024-09-21 13:36:53 +02:00
c10f71a867
Make the plugin work with Python 3.12 2024-09-21 12:11:06 +02:00
3 changed files with 88 additions and 50 deletions

View File

@ -51,7 +51,7 @@ __url__ = '' # 'http://supybot.com/Members/yourname/Deploy/download'
from . import config
from . import plugin
from imp import reload
from importlib import reload
reload(config) # In case we're being reloaded.
reload(plugin)

View File

@ -1,4 +1,3 @@
###
# Copyright (c) 2014, scythetwirler
# Copyright (c) 2024, Stanislas Daniel Claude Dolcini
# All rights reserved.
@ -27,35 +26,11 @@
# 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."""
@ -63,33 +38,35 @@ class wfg(callbacks.Plugin):
self.__parent = super(wfg, self)
self.__parent.__init__(irc)
self.ticket_pattern = re.compile(r"(?:^|\W)#(\d+)")
self.title_pattern = re.compile(r"\s-\s0ad\s-\s*Wildfire Games\s*$")
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')
ticket_url = self.registryValue('ticketUrl')
for ticket_number in sorted(set(self.ticket_pattern.findall(payload))):
url = f'{ticket_url.rstrip("/")}/{ticket_number}'
self.log.info(f'Fetching title for {url}')
# 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-\s0ad\s-\s*Wildfire Games\s*$', '', title)
except Exception as e:
response = urllib.request.urlopen(url)
html = response.read().decode()
except Exception:
return
title_match = re.search(r"<title>(.*)</title>", html)
title = title_match[1].strip() if title_match else "No title found"
# Clean up the title if necessary
title = self.title_pattern.sub('', title)
response = f'{title}{response.url}'
irc.queueMsg(ircmsgs.privmsg(channel, response))

83
test.py
View File

@ -51,7 +51,7 @@ class WFGTestCase(PluginTestCase):
msg = self.irc.takeMsg()
count += 1
self.assertEquals(count, 0)
self.assertEqual(count, 0)
obj.doPrivmsg(
self.irc,
@ -60,13 +60,13 @@ class WFGTestCase(PluginTestCase):
count = 0
msg = self.irc.takeMsg()
while msg is not None:
self.assertEquals(msg.nick, "")
self.assertEquals(msg.args[0], self.config["supybot.plugins.wfg.channels"][0])
self.assertEquals(msg.args[1], "#666 - Remove Devil – https://gitea.wildfiregames.com/0ad/0ad/issues/666")
self.assertEqual(msg.nick, "")
self.assertEqual(msg.args[0], self.config["supybot.plugins.wfg.channels"][0])
self.assertEqual(msg.args[1], "#666 - Remove Devil – https://gitea.wildfiregames.com/0ad/0ad/issues/666")
msg = self.irc.takeMsg()
count += 1
self.assertEquals(count, 1)
self.assertEqual(count, 1)
def testPullRequestUrl(self):
obj = self.irc.getCallback('wfg')
@ -80,7 +80,7 @@ class WFGTestCase(PluginTestCase):
msg = self.irc.takeMsg()
count += 1
self.assertEquals(count, 0)
self.assertEqual(count, 0)
obj.doPrivmsg(
self.irc,
@ -89,11 +89,72 @@ class WFGTestCase(PluginTestCase):
count = 0
msg = self.irc.takeMsg()
while msg is not None:
self.assertEquals(msg.nick, "")
self.assertEquals(msg.args[0], self.config["supybot.plugins.wfg.channels"][0])
self.assertEquals(msg.args[1], "#7028 - Add yamllint to pre-commit – https://gitea.wildfiregames.com/0ad/0ad/pulls/7028")
self.assertEqual(msg.nick, "")
self.assertEqual(msg.args[0], self.config["supybot.plugins.wfg.channels"][0])
self.assertEqual(msg.args[1], "#7028 - Add yamllint to pre-commit – https://gitea.wildfiregames.com/0ad/0ad/pulls/7028")
msg = self.irc.takeMsg()
count += 1
self.assertEquals(count, 1)
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
self.assertEqual(count, 1)
def test_dont_match_in_word(self):
obj = self.irc.getCallback('wfg')
obj.doPrivmsg(
self.irc,
ircmsgs.privmsg(self.config["supybot.plugins.wfg.channels"][0],
"https://example.tld/foo#1234")
)
self.assertIsNone(self.irc.takeMsg())
def test_ticket_id_at_the_beginning(self):
obj = self.irc.getCallback('wfg')
obj.doPrivmsg(
self.irc,
ircmsgs.privmsg(self.config["supybot.plugins.wfg.channels"][0],
"#1234 should be fine")
)
msg = self.irc.takeMsg()
self.assertIsInstance(msg, ircmsgs.IrcMsg)
self.assertEqual(msg.nick, "")
self.assertEqual(msg.args[0], self.config["supybot.plugins.wfg.channels"][0])
self.assertEqual(msg.args[1],
"#1234 - [PATCH] Read formations from json files – "
"https://gitea.wildfiregames.com/0ad/0ad/issues/1234")
self.assertIsNone(self.irc.takeMsg())
def test_match_multiple_ticket_ids(self):
obj = self.irc.getCallback('wfg')
obj.doPrivmsg(
self.irc,
ircmsgs.privmsg(self.config["supybot.plugins.wfg.channels"][0],
"References for this are #1234, #1234,#1235 and #1236")
)
msg = self.irc.takeMsg()
self.assertIsInstance(msg, ircmsgs.IrcMsg)
self.assertEqual(msg.nick, "")
self.assertEqual(msg.args[0], self.config["supybot.plugins.wfg.channels"][0])
self.assertEqual(msg.args[1],
"#1234 - [PATCH] Read formations from json files – "
"https://gitea.wildfiregames.com/0ad/0ad/issues/1234")
msg = self.irc.takeMsg()
self.assertIsInstance(msg, ircmsgs.IrcMsg)
self.assertEqual(msg.nick, "")
self.assertEqual(msg.args[0], self.config["supybot.plugins.wfg.channels"][0])
self.assertEqual(msg.args[1],
"#1235 - selection box moves when moving the camera – "
"https://gitea.wildfiregames.com/0ad/0ad/issues/1235")
msg = self.irc.takeMsg()
self.assertIsInstance(msg, ircmsgs.IrcMsg)
self.assertEqual(msg.nick, "")
self.assertEqual(msg.args[0], self.config["supybot.plugins.wfg.channels"][0])
self.assertEqual(msg.args[1],
"#1236 - WP Theming - Fine Footer – "
"https://gitea.wildfiregames.com/0ad/0ad/issues/1236")
self.assertIsNone(self.irc.takeMsg())