Hello community,

here is the log from the commit of package python-limnoria for openSUSE:Factory 
checked in at 2019-09-13 14:58:10
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-limnoria (Old)
 and      /work/SRC/openSUSE:Factory/.python-limnoria.new.7948 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-limnoria"

Fri Sep 13 14:58:10 2019 rev:8 rq:730097 version:2019.09.08

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-limnoria/python-limnoria.changes  
2019-03-26 22:32:00.709711730 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-limnoria.new.7948/python-limnoria.changes    
    2019-09-13 14:58:20.289277286 +0200
@@ -1,0 +2,12 @@
+Wed Sep 11 07:47:17 UTC 2019 - Atri Bhattacharya <[email protected]>
+
+- Update to version 2019-09-08:
+  * Interpret empty server tag values as missing tag values. As
+    required by https://ircv3.net/specs/extensions/message-tags
+- Changes from version 2019-08-25:
+  * Config: Prevent accidental leak of private values on public
+    channels.
+- Changes from version 2019-07-17:
+  * Google: Update for Google's new HTML layout.
+
+-------------------------------------------------------------------

Old:
----
  master-2019-02-23.tar.gz

New:
----
  master-2019-09-08.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-limnoria.spec ++++++
--- /var/tmp/diff_new_pack.Q09oJQ/_old  2019-09-13 14:58:20.717277304 +0200
+++ /var/tmp/diff_new_pack.Q09oJQ/_new  2019-09-13 14:58:20.717277304 +0200
@@ -12,15 +12,15 @@
 # license that conforms to the Open Source Definition (Version 1.9)
 # published by the Open Source Initiative.
 
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
 #
 
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %define appname limnoria
-%define srcver 2019-02-23
+%define srcver 2019-09-08
 Name:           python-limnoria
-Version:        2019.02.23
+Version:        2019.09.08
 Release:        0
 Summary:        A modified version of Supybot (an IRC bot and framework)
 License:        BSD-3-Clause

++++++ master-2019-02-23.tar.gz -> master-2019-09-08.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Limnoria-master-2019-02-23/plugins/Aka/plugin.py 
new/Limnoria-master-2019-09-08/plugins/Aka/plugin.py
--- old/Limnoria-master-2019-02-23/plugins/Aka/plugin.py        2019-02-23 
00:12:06.000000000 +0100
+++ new/Limnoria-master-2019-09-08/plugins/Aka/plugin.py        2019-09-08 
14:47:05.000000000 +0200
@@ -555,7 +555,7 @@
         channel = 'global'
         for (option, arg) in optlist:
             if option == 'channel':
-                if not ircutils.isChannel(arg):
+                if not irc.isChannel(arg):
                     irc.error(_('%r is not a valid channel.') % arg,
                             Raise=True)
                 channel = arg
@@ -587,7 +587,7 @@
         channel = 'global'
         for (option, arg) in optlist:
             if option == 'channel':
-                if not ircutils.isChannel(arg):
+                if not irc.isChannel(arg):
                     irc.error(_('%r is not a valid channel.') % arg,
                             Raise=True)
                 channel = arg
@@ -618,7 +618,7 @@
         channel = 'global'
         for (option, arg) in optlist:
             if option == 'channel':
-                if not ircutils.isChannel(arg):
+                if not irc.isChannel(arg):
                     irc.error(_('%r is not a valid channel.') % arg,
                             Raise=True)
                 channel = arg
@@ -650,7 +650,7 @@
         channel = 'global'
         for (option, arg) in optlist:
             if option == 'channel':
-                if not ircutils.isChannel(arg):
+                if not irc.isChannel(arg):
                     irc.error(_('%r is not a valid channel.') % arg,
                             Raise=True)
                 channel = arg
@@ -673,7 +673,7 @@
         channel = 'global'
         for (option, arg) in optlist:
             if option == 'channel':
-                if not ircutils.isChannel(arg):
+                if not irc.isChannel(arg):
                     irc.error(_('%r is not a valid channel.') % arg,
                             Raise=True)
                 channel = arg
@@ -696,7 +696,7 @@
         channel = 'global'
         for (option, arg) in optlist:
             if option == 'channel':
-                if not ircutils.isChannel(arg):
+                if not irc.isChannel(arg):
                     irc.error(_('%r is not a valid channel.') % arg,
                             Raise=True)
                 channel = arg
@@ -742,7 +742,7 @@
         filterlocked = filterunlocked = False
         for (option, arg) in optlist:
             if option == 'channel':
-                if not ircutils.isChannel(arg):
+                if not irc.isChannel(arg):
                     irc.error(_('%r is not a valid channel.') % arg,
                             Raise=True)
                 channel = arg
@@ -785,7 +785,7 @@
         channel = 'global'
         for (option, arg) in optlist:
             if option == 'channel':
-                if not ircutils.isChannel(arg):
+                if not irc.isChannel(arg):
                     irc.error(_('%r is not a valid channel.') % arg,
                             Raise=True)
                 channel = arg
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Limnoria-master-2019-02-23/plugins/Alias/plugin.py 
new/Limnoria-master-2019-09-08/plugins/Alias/plugin.py
--- old/Limnoria-master-2019-02-23/plugins/Alias/plugin.py      2019-02-23 
00:12:06.000000000 +0100
+++ new/Limnoria-master-2019-09-08/plugins/Alias/plugin.py      2019-09-08 
14:47:05.000000000 +0200
@@ -43,13 +43,13 @@
 _ = PluginInternationalization('Alias')
 
 # Copied from the old privmsgs.py.
-def getChannel(msg, args=()):
+def getChannel(irc, msg, args):
     """Returns the channel the msg came over or the channel given in args.
 
     If the channel was given in args, args is modified (the channel is
     removed).
     """
-    if args and ircutils.isChannel(args[0]):
+    if args and irc.isChannel(msg.args[0]):
         if conf.supybot.reply.requireChannelCommandsToBeSentInChannel():
             if args[0] != msg.args[0]:
                 s = 'Channel commands must be sent in the channel to which ' \
@@ -60,7 +60,7 @@
                     'to False.'
                 raise callbacks.Error(s)
         return args.pop(0)
-    elif ircutils.isChannel(msg.args[0]):
+    elif irc.isChannel(msg.args[0]):
         return msg.args[0]
     else:
         raise callbacks.Error('Command must be sent in a channel or ' \
@@ -173,7 +173,7 @@
     def f(self, irc, msg, args):
         alias = original.replace('$nick', msg.nick)
         if '$channel' in original:
-            channel = getChannel(msg, args)
+            channel = getChannel(irc, msg, args)
             alias = alias.replace('$channel', channel)
         tokens = callbacks.tokenize(alias)
         if biggestDollar or biggestAt:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/Limnoria-master-2019-02-23/plugins/BadWords/plugin.py 
new/Limnoria-master-2019-09-08/plugins/BadWords/plugin.py
--- old/Limnoria-master-2019-02-23/plugins/BadWords/plugin.py   2019-02-23 
00:12:06.000000000 +0100
+++ new/Limnoria-master-2019-09-08/plugins/BadWords/plugin.py   2019-09-08 
14:47:05.000000000 +0200
@@ -75,7 +75,7 @@
             channel = msg.args[0]
             self.updateRegexp(channel)
             s = ircutils.stripFormatting(msg.args[1])
-            if ircutils.isChannel(channel) and self.registryValue('kick', 
channel):
+            if irc.isChannel(channel) and self.registryValue('kick', channel):
                 if self.regexp.search(s):
                     c = irc.state.channels[channel]
                     cap = ircdb.makeChannelCapability(channel, 'op')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Limnoria-master-2019-02-23/plugins/Channel/plugin.py 
new/Limnoria-master-2019-09-08/plugins/Channel/plugin.py
--- old/Limnoria-master-2019-02-23/plugins/Channel/plugin.py    2019-02-23 
00:12:06.000000000 +0100
+++ new/Limnoria-master-2019-09-08/plugins/Channel/plugin.py    2019-09-08 
14:47:05.000000000 +0200
@@ -912,7 +912,7 @@
         if 's' in irc.state.channels[channel].modes and \
             msg.args[0] != channel and \
             not ircdb.checkCapability(msg.prefix, capability) and \
-            (ircutils.isChannel(msg.args[0]) or \
+            (irc.isChannel(msg.args[0]) or \
              msg.nick not in irc.state.channels[channel].users):
             irc.error(_('You don\'t have access to that information.'),
                     Raise=True)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/Limnoria-master-2019-02-23/plugins/ChannelLogger/plugin.py 
new/Limnoria-master-2019-09-08/plugins/ChannelLogger/plugin.py
--- old/Limnoria-master-2019-02-23/plugins/ChannelLogger/plugin.py      
2019-02-23 00:12:06.000000000 +0100
+++ new/Limnoria-master-2019-09-08/plugins/ChannelLogger/plugin.py      
2019-09-08 14:47:05.000000000 +0200
@@ -35,6 +35,7 @@
 import supybot.conf as conf
 import supybot.world as world
 import supybot.ircdb as ircdb
+import supybot.utils as utils
 import supybot.irclib as irclib
 import supybot.utils.minisix as minisix
 import supybot.ircmsgs as ircmsgs
@@ -95,9 +96,10 @@
 
     def getLogName(self, channel):
         if self.registryValue('rotateLogs', channel):
-            return '%s.%s.log' % (channel, self.logNameTimestamp(channel))
+            name = '%s.%s.log' % (channel, self.logNameTimestamp(channel))
         else:
-            return '%s.log' % channel
+            name = '%s.log' % channel
+        return utils.file.sanitizeName(name)
 
     def getLogDir(self, irc, channel):
         channel = self.normalizeChannel(irc, channel)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/Limnoria-master-2019-02-23/plugins/ChannelLogger/test.py 
new/Limnoria-master-2019-09-08/plugins/ChannelLogger/test.py
--- old/Limnoria-master-2019-02-23/plugins/ChannelLogger/test.py        
2019-02-23 00:12:06.000000000 +0100
+++ new/Limnoria-master-2019-09-08/plugins/ChannelLogger/test.py        
2019-09-08 14:47:05.000000000 +0200
@@ -32,5 +32,13 @@
 class ChannelLoggerTestCase(PluginTestCase):
     plugins = ('ChannelLogger',)
 
+    def testLogDir(self):
+        self.assertEqual(
+            self.irc.getCallback('ChannelLogger').getLogName('#foo'),
+            '#foo.log')
+        self.assertEqual(
+            self.irc.getCallback('ChannelLogger').getLogName('#f/../oo'),
+            '#f..oo.log')
+
 
 # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/Limnoria-master-2019-02-23/plugins/ChannelStats/plugin.py 
new/Limnoria-master-2019-09-08/plugins/ChannelStats/plugin.py
--- old/Limnoria-master-2019-02-23/plugins/ChannelStats/plugin.py       
2019-02-23 00:12:06.000000000 +0100
+++ new/Limnoria-master-2019-09-08/plugins/ChannelStats/plugin.py       
2019-09-08 14:47:05.000000000 +0200
@@ -141,8 +141,8 @@
         else:
             return UserStat(*L)
 
-    def addMsg(self, msg, id=None):
-        if msg.args and ircutils.isChannel(msg.args[0]):
+    def addMsg(self, irc, msg, id=None):
+        if msg.args and irc.isChannel(msg.args[0]):
             channel = plugins.getChannel(msg.args[0])
             if (channel, 'channelStats') not in self:
                 self[channel, 'channelStats'] = ChannelStat()
@@ -181,16 +181,16 @@
         self.__parent.die()
 
     def __call__(self, irc, msg):
-        self.db.addMsg(msg)
+        self.db.addMsg(irc, msg)
         super(ChannelStats, self).__call__(irc, msg)
 
     def outFilter(self, irc, msg):
         if msg.command == 'PRIVMSG':
-            if ircutils.isChannel(msg.args[0]):
+            if irc.isChannel(msg.args[0]):
                 if self.registryValue('selfStats', msg.args[0]):
                     try:
                         self.outFiltering = True
-                        self.db.addMsg(msg, 0)
+                        self.db.addMsg(irc, msg, 0)
                     finally:
                         self.outFiltering = False
         return msg
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Limnoria-master-2019-02-23/plugins/Config/plugin.py 
new/Limnoria-master-2019-09-08/plugins/Config/plugin.py
--- old/Limnoria-master-2019-02-23/plugins/Config/plugin.py     2019-02-23 
00:12:06.000000000 +0100
+++ new/Limnoria-master-2019-09-08/plugins/Config/plugin.py     2019-09-08 
14:47:05.000000000 +0200
@@ -63,7 +63,7 @@
             raise registry.InvalidRegistryName(name)
     return group
 
-def getCapability(name):
+def getCapability(irc, name):
     capability = 'owner' # Default to requiring the owner capability.
     if not name.startswith('supybot') and not name.startswith('users'):
         name = 'supybot.' + name
@@ -74,7 +74,7 @@
         group = group.get(part)
         if not getattr(group, '_opSettable', True):
             return 'owner'
-        if ircutils.isChannel(part):
+        if irc.isChannel(part):
             # If a registry value has a channel in it, it requires a
             # 'channel,op' capability, or so we assume.  We'll see if we're
             # proven wrong.
@@ -148,15 +148,15 @@
         except registry.InvalidRegistryValue as e:
             irc.error(str(e))
 
-    def _list(self, group):
+    def _list(self, irc, group):
         L = []
         for (vname, v) in group._children.items():
             if hasattr(group, 'channelValue') and group.channelValue and \
-               ircutils.isChannel(vname) and not v._children:
+               irc.isChannel(vname) and not v._children:
                 continue
             if hasattr(v, 'channelValue') and v.channelValue:
                 vname = '#' + vname
-            if v._added and not all(ircutils.isChannel, v._added):
+            if v._added and not all(irc.isChannel, v._added):
                 vname = '@' + vname
             L.append(vname)
         utils.sortBy(str.lower, L)
@@ -172,7 +172,7 @@
         it can be separately configured for each channel using the 'channel'
         command in this plugin, it is preceded by an '#' sign.
         """
-        L = self._list(group)
+        L = self._list(irc, group)
         if L:
             irc.reply(format('%L', L))
         else:
@@ -190,7 +190,7 @@
         for (name, x) in conf.supybot.getValues(getChildren=True):
             if word in name.lower():
                 possibleChannel = registry.split(name)[-1]
-                if not ircutils.isChannel(possibleChannel):
+                if not irc.isChannel(possibleChannel):
                     L.append(name)
         if L:
             irc.reply(format('%L', L))
@@ -207,7 +207,7 @@
             if not group._private:
                 return (value, None)
             else:
-                capability = getCapability(group._name)
+                capability = getCapability(irc, group._name)
                 if ircdb.checkCapability(msg.prefix, capability):
                     return (value, True)
                 else:
@@ -222,7 +222,7 @@
             irc.error(_("This configuration variable is not writeable "
                 "via IRC. To change it you have to: 1) use the 'flush' command 
2) edit "
                 "the config file 3) use the 'config reload' command."), 
Raise=True)
-        capability = getCapability(group._name)
+        capability = getCapability(irc, group._name)
         if ircdb.checkCapability(msg.prefix, capability):
             # I think callCommand catches exceptions here.  Should it?
             group.set(value)
@@ -256,11 +256,11 @@
                 if private_value:
                     private = True
             if len(channels) > 1:
-                irc.reply('; '.join([
-                    '%s: %s' % (channel, value)
-                    for (channel, value) in values]))
+                irc.reply('; '.join(['%s: %s' % (channel, value)
+                                     for (channel, value) in values]),
+                          private=private)
             else:
-                irc.reply(values[0][1])
+                irc.reply(values[0][1], private=private)
     channel = wrap(channel, ['channels', 'settableConfigVar',
                              additional('text')])
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/Limnoria-master-2019-02-23/plugins/Factoids/plugin.py 
new/Limnoria-master-2019-09-08/plugins/Factoids/plugin.py
--- old/Limnoria-master-2019-02-23/plugins/Factoids/plugin.py   2019-02-23 
00:12:06.000000000 +0100
+++ new/Limnoria-master-2019-09-08/plugins/Factoids/plugin.py   2019-09-08 
14:47:05.000000000 +0200
@@ -128,7 +128,7 @@
             self.write(httpserver.get_template('factoids/index.html'))
         elif len(parts) == 2:
             channel = utils.web.urlunquote(parts[0])
-            if not ircutils.isChannel(channel):
+            if not irc.isChannel(channel):
                 self.send_response(404)
                 self.send_header('Content-type', 'text/html; charset=utf-8')
                 self.end_headers()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Limnoria-master-2019-02-23/plugins/Google/plugin.py 
new/Limnoria-master-2019-09-08/plugins/Google/plugin.py
--- old/Limnoria-master-2019-02-23/plugins/Google/plugin.py     2019-02-23 
00:12:06.000000000 +0100
+++ new/Limnoria-master-2019-09-08/plugins/Google/plugin.py     2019-09-08 
14:47:05.000000000 +0200
@@ -75,13 +75,13 @@
             msg = ircmsgs.privmsg(msg.args[0], s, msg=msg)
         return msg
 
-    _decode_re = re.compile(r'<h3 class="r"><a 
href="/url\?q=(?P<url>[^"]+)&[^"]+">(?P<title>.*?)</a></h3>.*?<a class="[^"]+" 
href="/url\?q=(?P<cacheUrl>http://webcache[^"]+)">.*?<span 
class="st">(?P<content>.*?)</span>', re.DOTALL | re.MULTILINE)
+    _decode_re = re.compile(r'<div class="\w+"><a 
href="/url\?q=(?P<url>[^"]+)&[^"]+"><div class="(\w| 
)+">(?P<title>.*?)</div><div class="(\w| 
)+">(?P<breadcrumbs>.*?)</div></a></div>(?P<content><div class="(\w| 
)+">.*?</div></div>)', re.DOTALL | re.MULTILINE)
     @classmethod
     def decode(cls, text):
-        matches = cls._decode_re.findall(text)
+        matches = cls._decode_re.finditer(text)
         results = []
         for match in matches:
-            r = dict(zip(('url', 'title', 'cacheUrl', 'content'), match))
+            r = match.groupdict()
             r['url'] = 
utils.web.urlunquote(utils.web.htmlToText(r['url'].split('&amp;')[0]))
             results.append(r)
         return results
@@ -326,7 +326,7 @@
         Uses Google's calculator to calculate the value of <expression>.
         """
         channel = msg.args[0]
-        if not ircutils.isChannel(channel):
+        if not irc.isChannel(channel):
             channel = None
         url = self._googleUrl(expr, channel)
         h = {"User-Agent":"Mozilla/5.0 (Windows NT 6.2; Win64; x64) 
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1667.0 Safari/537.36"}
@@ -360,7 +360,7 @@
         Looks <phone number> up on Google.
         """
         channel = msg.args[0]
-        if not ircutils.isChannel(channel):
+        if not irc.isChannel(channel):
             channel = None
         url = self._googleUrl(phonenumber, channel)
         html = utils.web.getUrl(url).decode('utf8')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Limnoria-master-2019-02-23/plugins/Later/config.py 
new/Limnoria-master-2019-09-08/plugins/Later/config.py
--- old/Limnoria-master-2019-02-23/plugins/Later/config.py      2019-02-23 
00:12:06.000000000 +0100
+++ new/Limnoria-master-2019-09-08/plugins/Later/config.py      2019-09-08 
14:47:05.000000000 +0200
@@ -56,4 +56,9 @@
     days that a message will remain queued for a user. After this time elapses,
     the message will be deleted. If this value is 0, there is no maximum.""")))
 
+conf.registerGroup(Later, 'format')
+conf.registerGlobalValue(Later.format, 'senderHostname',
+    registry.Boolean(False, _("""Determines whether senders' hostname will be
+    shown in messages (instead of just the nick).""")))
+
 # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Limnoria-master-2019-02-23/plugins/Later/plugin.py 
new/Limnoria-master-2019-09-08/plugins/Later/plugin.py
--- old/Limnoria-master-2019-02-23/plugins/Later/plugin.py      2019-02-23 
00:12:06.000000000 +0100
+++ new/Limnoria-master-2019-09-08/plugins/Later/plugin.py      2019-09-08 
14:47:05.000000000 +0200
@@ -150,7 +150,7 @@
         full_queues = []
         for validnick in validnicks:
             try:
-                self._addNote(validnick, msg.nick, text)
+                self._addNote(validnick, msg.prefix, text)
             except QueueIsFull:
                 full_queues.append(validnick)
         if full_queues:
@@ -210,7 +210,7 @@
             return
         self._notes[nick].reverse()
         for note in self._notes[nick]:
-            if note[1] == msg.nick:
+            if ircutils.nickFromHostmask(note[1]) == msg.nick:
                 self._notes[nick].remove(note)
                 if len(self._notes[nick]) == 0:
                     del self._notes[nick]
@@ -243,6 +243,8 @@
             msg.tag('repliedTo', old_repliedto)
 
     def _formatNote(self, when, whence, note):
+        if not self.registryValue('format.senderHostname'):
+            whence = ircutils.nickFromHostmask(whence)
         return _('Sent %s: <%s> %s') % (self._timestamp(when), whence, note)
 
     def doJoin(self, irc, msg):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Limnoria-master-2019-02-23/plugins/Later/test.py 
new/Limnoria-master-2019-09-08/plugins/Later/test.py
--- old/Limnoria-master-2019-02-23/plugins/Later/test.py        2019-02-23 
00:12:06.000000000 +0100
+++ new/Limnoria-master-2019-09-08/plugins/Later/test.py        2019-09-08 
14:47:05.000000000 +0200
@@ -28,6 +28,7 @@
 ###
 
 from supybot.test import *
+import supybot.conf as conf
 import time
 
 class LaterTestCase(ChannelPluginTestCase):
@@ -126,6 +127,16 @@
         self.assertEqual(str(m).strip(),
                 'PRIVMSG #test :bar: Sent 1 minute ago: <test> more stuff')
         time.time = real_time
-        
+
+    def testSenderHostname(self):
+        self.assertNotError('later tell foo stuff')
+        testPrefix = 'foo!bar@baz'
+        with conf.supybot.plugins.Later.format.senderHostname.context(True):
+            self.irc.feedMsg(ircmsgs.privmsg(self.channel, 'something',
+                                             prefix=testPrefix))
+            m = self.getMsg(' ')
+        self.assertEqual(str(m).strip(),
+                'PRIVMSG #test :foo: Sent just now: <%s> stuff' % self.prefix)
+ 
 # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Limnoria-master-2019-02-23/plugins/Misc/plugin.py 
new/Limnoria-master-2019-09-08/plugins/Misc/plugin.py
--- old/Limnoria-master-2019-02-23/plugins/Misc/plugin.py       2019-02-23 
00:12:06.000000000 +0100
+++ new/Limnoria-master-2019-09-08/plugins/Misc/plugin.py       2019-09-08 
14:47:05.000000000 +0200
@@ -34,6 +34,7 @@
 import sys
 import json
 import time
+import functools
 
 
 import supybot
@@ -402,10 +403,10 @@
             irc.error(_('That\'s all, there is no more.'))
     more = wrap(more, [additional('seenNick')])
 
-    def _validLastMsg(self, msg):
+    def _validLastMsg(self, irc, msg):
         return msg.prefix and \
                msg.command == 'PRIVMSG' and \
-               ircutils.isChannel(msg.args[0])
+               irc.isChannel(msg.args[0])
 
     @internationalizeDocstring
     def last(self, irc, msg, args, optlist):
@@ -422,7 +423,7 @@
         predicates = {}
         nolimit = False
         skipfirst = True
-        if ircutils.isChannel(msg.args[0]):
+        if irc.isChannel(msg.args[0]):
             predicates['in'] = lambda m: ircutils.strEqual(m.args[0],
                                                            msg.args[0])
         else:
@@ -469,7 +470,8 @@
                 predicates.setdefault('regexp', []).append(f)
             elif option == 'nolimit':
                 nolimit = True
-        iterable = filter(self._validLastMsg, reversed(irc.state.history))
+        iterable = filter(functools.partial(self._validLastMsg, irc),
+                          reversed(irc.state.history))
         if skipfirst:
             # Drop the first message only if our current channel is the same as
             # the channel we've been instructed to look at.
@@ -535,7 +537,7 @@
             irc.error('This command cannot be nested.', Raise=True)
         if target.lower() == 'me':
             target = msg.nick
-        if ircutils.isChannel(target):
+        if irc.isChannel(target):
             irc.error(_('Hey, just give the command.  No need for the tell.'))
             return
         if not ircutils.isNick(target):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Limnoria-master-2019-02-23/plugins/Network/plugin.py 
new/Limnoria-master-2019-09-08/plugins/Network/plugin.py
--- old/Limnoria-master-2019-02-23/plugins/Network/plugin.py    2019-02-23 
00:12:06.000000000 +0100
+++ new/Limnoria-master-2019-09-08/plugins/Network/plugin.py    2019-09-08 
14:47:05.000000000 +0200
@@ -108,12 +108,11 @@
 
     @internationalizeDocstring
     def disconnect(self, irc, msg, args, otherIrc, quitMsg):
-        """[<network>] [<quit message>]
+        """<network> [<quit message>]
 
         Disconnects from the network represented by the network <network>.
         If <quit message> is given, quits the network with the given quit
-        message.  <network> is only necessary if the network is different
-        from the network the command is sent on.
+        message.
         """
         standard_msg = conf.supybot.plugins.Owner.quitMsg()
         if standard_msg:
@@ -125,7 +124,7 @@
         if otherIrc != irc:
             irc.replySuccess(_('Disconnection to %s initiated.') %
                              otherIrc.network)
-    disconnect = wrap(disconnect, ['owner', 'networkIrc', additional('text')])
+    disconnect = wrap(disconnect, ['owner', ('networkIrc', True), 
additional('text')])
 
     @internationalizeDocstring
     def reconnect(self, irc, msg, args, otherIrc, quitMsg):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/Limnoria-master-2019-02-23/plugins/NickCapture/plugin.py 
new/Limnoria-master-2019-09-08/plugins/NickCapture/plugin.py
--- old/Limnoria-master-2019-02-23/plugins/NickCapture/plugin.py        
2019-02-23 00:12:06.000000000 +0100
+++ new/Limnoria-master-2019-09-08/plugins/NickCapture/plugin.py        
2019-09-08 14:47:05.000000000 +0200
@@ -120,7 +120,7 @@
 
     def do437(self, irc, msg):
         """Nick/channel is temporarily unavailable"""
-        if ircutils.isChannel(msg.args[1]):
+        if irc.isChannel(msg.args[1]):
             return
         self.log.info('Nick %s is unavailable; attempting NickServ release '
                       'on %s.' % (msg.args[1], irc.network))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/Limnoria-master-2019-02-23/plugins/Nickometer/plugin.py 
new/Limnoria-master-2019-09-08/plugins/Nickometer/plugin.py
--- old/Limnoria-master-2019-02-23/plugins/Nickometer/plugin.py 2019-02-23 
00:12:06.000000000 +0100
+++ new/Limnoria-master-2019-09-08/plugins/Nickometer/plugin.py 2019-09-08 
14:47:05.000000000 +0200
@@ -45,8 +45,6 @@
 #    #
 ###
 
-from __future__ import division
-
 import supybot
 
 import re
@@ -224,7 +222,7 @@
 
         # Use an appropriate function to map [0, +inf) to [0, 100)
         percentage = 100 * (1 + math.tanh((score - 400.0) / 400.0)) * \
-                     (1 - 1 / (1 + score / 5.0)) // 2
+                     (1 - 1 / (1 + score / 5.0)) / 2
 
         # if it's above 99.9%, show as many digits as is interesting
         score_string=re.sub('(99\\.9*\\d|\\.\\d).*','\\1',repr(percentage))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/Limnoria-master-2019-02-23/plugins/Nickometer/test.py 
new/Limnoria-master-2019-09-08/plugins/Nickometer/test.py
--- old/Limnoria-master-2019-02-23/plugins/Nickometer/test.py   2019-02-23 
00:12:06.000000000 +0100
+++ new/Limnoria-master-2019-09-08/plugins/Nickometer/test.py   2019-09-08 
14:47:05.000000000 +0200
@@ -33,6 +33,12 @@
     plugins = ('Nickometer',)
     def testNickometer(self):
         self.assertNotError('nickometer')
-        self.assertNotError('nickometer jemfinch')
+        self.assertResponse(
+            'nickometer jemfinch',
+            'The "lame nick-o-meter" reading for "jemfinch" is 0.0%.')
+        nick = 'xXReallyObnoxious1337NickXx'
+        self.assertResponse(
+            'nickometer %s' % nick,
+            'The "lame nick-o-meter" reading for "%s" is 99.96%%.' % nick)
 
 # vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Limnoria-master-2019-02-23/plugins/Note/plugin.py 
new/Limnoria-master-2019-09-08/plugins/Note/plugin.py
--- old/Limnoria-master-2019-02-23/plugins/Note/plugin.py       2019-02-23 
00:12:06.000000000 +0100
+++ new/Limnoria-master-2019-09-08/plugins/Note/plugin.py       2019-09-08 
14:47:05.000000000 +0200
@@ -270,8 +270,8 @@
         self.db.setRead(id)
     note = wrap(note, ['user', ('id', 'note')])
 
-    def _formatNoteId(self, msg, note, sent=False):
-        if note.public or not ircutils.isChannel(msg.args[0]):
+    def _formatNoteId(self, irc, msg, note, sent=False):
+        if note.public or not irc.isChannel(msg.args[0]):
             if sent:
                 sender = plugins.getUserName(note.to)
                 return format('#%i to %s', note.id, sender)
@@ -315,7 +315,7 @@
             irc.reply('No matching notes were found.')
         else:
             utils.sortBy(operator.attrgetter('id'), notes)
-            ids = [self._formatNoteId(msg, note) for note in notes]
+            ids = [self._formatNoteId(irc, msg, note) for note in notes]
             ids = self._condense(ids)
             irc.reply(format('%L', ids))
     search = wrap(search,
@@ -357,7 +357,7 @@
             irc.reply('You have no unread notes.')
         else:
             utils.sortBy(operator.attrgetter('id'), notes)
-            ids = [self._formatNoteId(msg, note) for note in notes]
+            ids = [self._formatNoteId(irc, msg, note) for note in notes]
             ids = self._condense(ids)
             irc.reply(format('%L.', ids))
     list = wrap(list, ['user', getopts({'old': '', 'sent': '',
@@ -421,7 +421,7 @@
         else:
             utils.sortBy(operator.attrgetter('id'), notes)
             notes.reverse() # Most recently sent first.
-            ids = [self._formatNoteId(msg, note, sent=True) for note in notes]
+            ids = [self._formatNoteId(irc, msg, note, sent=True) for note in 
notes]
             ids = self._condense(ids)
             irc.reply(format('%L.', ids))
 
@@ -444,7 +444,7 @@
         else:
             utils.sortBy(operator.attrgetter('id'), notes)
             notes.reverse()
-            ids = [self._formatNoteId(msg, note) for note in notes]
+            ids = [self._formatNoteId(irc, msg, note) for note in notes]
             ids = self._condense(ids)
             irc.reply(format('%L.', ids))
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/Limnoria-master-2019-02-23/plugins/PluginDownloader/plugin.py 
new/Limnoria-master-2019-09-08/plugins/PluginDownloader/plugin.py
--- old/Limnoria-master-2019-02-23/plugins/PluginDownloader/plugin.py   
2019-02-23 00:12:06.000000000 +0100
+++ new/Limnoria-master-2019-09-08/plugins/PluginDownloader/plugin.py   
2019-09-08 14:47:05.000000000 +0200
@@ -289,12 +289,21 @@
                                                    'skgsergio',
                                                    'Limnoria-plugins',
                                                    ),
+               'jlu5':             GithubRepository(
+                                                   'jlu5',
+                                                   'SupyPlugins',
+                                                   ),
+               'jlu5-py2legacy':   GithubRepository(
+                                                   'jlu5',
+                                                   'SupyPlugins',
+                                                   branch='python2-legacy'
+                                                   ),
                'GLolol':           GithubRepository(
-                                                   'GLolol',
+                                                   'jlu5',
                                                    'SupyPlugins',
                                                    ),
                'GLolol-py2legacy': GithubRepository(
-                                                   'GLolol',
+                                                   'jlu5',
                                                    'SupyPlugins',
                                                    branch='python2-legacy'
                                                    ),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Limnoria-master-2019-02-23/plugins/RSS/plugin.py 
new/Limnoria-master-2019-09-08/plugins/RSS/plugin.py
--- old/Limnoria-master-2019-02-23/plugins/RSS/plugin.py        2019-02-23 
00:12:06.000000000 +0100
+++ new/Limnoria-master-2019-09-08/plugins/RSS/plugin.py        2019-09-08 
14:47:05.000000000 +0200
@@ -63,7 +63,7 @@
     from urllib.request import ProxyHandler
 
 def get_feedName(irc, msg, args, state):
-    if ircutils.isChannel(args[0]):
+    if irc.isChannel(args[0]):
         state.errorInvalid('feed name', args[0], 'must not be channel names.')
     if not registry.isValidRegistryName(args[0]):
         state.errorInvalid('feed name', args[0],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Limnoria-master-2019-02-23/plugins/Reply/test.py 
new/Limnoria-master-2019-09-08/plugins/Reply/test.py
--- old/Limnoria-master-2019-02-23/plugins/Reply/test.py        2019-02-23 
00:12:06.000000000 +0100
+++ new/Limnoria-master-2019-09-08/plugins/Reply/test.py        2019-09-08 
14:47:05.000000000 +0200
@@ -34,7 +34,7 @@
     plugins = ('Reply',)
     def testPrivate(self):
         m = self.getMsg('private [list]')
-        self.failIf(ircutils.isChannel(m.args[0]))
+        self.failIf(self.irc.isChannel(m.args[0]))
 
     def testNotice(self):
         m = self.getMsg('notice [list]')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/Limnoria-master-2019-02-23/plugins/Services/plugin.py 
new/Limnoria-master-2019-09-08/plugins/Services/plugin.py
--- old/Limnoria-master-2019-02-23/plugins/Services/plugin.py   2019-02-23 
00:12:06.000000000 +0100
+++ new/Limnoria-master-2019-09-08/plugins/Services/plugin.py   2019-09-08 
14:47:05.000000000 +0200
@@ -276,7 +276,7 @@
             chanTypes = irc.state.supported['CHANTYPES']
             if re.match(r'^\[[%s]' % re.escape(chanTypes), s):
                 self.log.debug('Got entrymsg from ChanServ %s.', on)
-        elif ircutils.isChannel(msg.args[0]):
+        elif irc.isChannel(msg.args[0]):
             # Atheme uses channel-wide notices for alerting channel access
             # changes if the FANTASY or VERBOSE setting is on; we can suppress
             # these 'unexpected notice' warnings since they're not really 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Limnoria-master-2019-02-23/plugins/Success/plugin.py 
new/Limnoria-master-2019-09-08/plugins/Success/plugin.py
--- old/Limnoria-master-2019-02-23/plugins/Success/plugin.py    2019-02-23 
00:12:06.000000000 +0100
+++ new/Limnoria-master-2019-09-08/plugins/Success/plugin.py    2019-09-08 
14:47:05.000000000 +0200
@@ -62,7 +62,7 @@
                 return ret
 
             def get(self, attr):
-                if ircutils.isChannel(attr):
+                if irc.isChannel(attr):
                     pluginSelf.target = attr
                 return self
         conf.supybot.replies.success.__class__ = MySuccessClass
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Limnoria-master-2019-02-23/plugins/__init__.py 
new/Limnoria-master-2019-09-08/plugins/__init__.py
--- old/Limnoria-master-2019-02-23/plugins/__init__.py  2019-02-23 
00:12:06.000000000 +0100
+++ new/Limnoria-master-2019-09-08/plugins/__init__.py  2019-09-08 
14:47:05.000000000 +0200
@@ -60,14 +60,15 @@
         def junk(*args, **kwargs):
             pass
         return junk
-    filename = conf.supybot.directories.data.dirize(filename)
     def MakeDB(*args, **kwargs):
         for type in conf.supybot.databases():
             # Can't do this because Python sucks.  Go ahead, try it!
             # filename = '.'.join([filename, type, 'db'])
             fn = '.'.join([filename, type, 'db'])
+            fn = utils.file.sanitizeName(fn)
+            path = conf.supybot.directories.data.dirize(fn)
             try:
-                return types[type](fn, *args, **kwargs)
+                return types[type](path, *args, **kwargs)
             except KeyError:
                 continue
         raise NoSuitableDatabase(types.keys())
@@ -78,11 +79,11 @@
     filename = os.path.basename(filename)
     channelSpecific = conf.supybot.databases.plugins.channelSpecific
     channel = channelSpecific.getChannelLink(channel)
-    channel = ircutils.toLower(channel)
+    channel = utils.file.sanitizeName(ircutils.toLower(channel))
     if dirname is None:
         dirname = conf.supybot.directories.data.dirize(channel)
     if not os.path.exists(dirname):
-            os.makedirs(dirname)
+        os.makedirs(dirname)
     return os.path.join(dirname, filename)
 
 def getChannel(channel):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Limnoria-master-2019-02-23/src/callbacks.py 
new/Limnoria-master-2019-09-08/src/callbacks.py
--- old/Limnoria-master-2019-02-23/src/callbacks.py     2019-02-23 
00:12:06.000000000 +0100
+++ new/Limnoria-master-2019-09-08/src/callbacks.py     2019-09-08 
14:47:05.000000000 +0200
@@ -470,7 +470,7 @@
             joiner = joiner.join
         to = self._getTarget(kwargs.get('to'))
         if oneToOne is None: # Can be True, False, or None
-            if ircutils.isChannel(to):
+            if self.irc.isChannel(to):
                 oneToOne = conf.get(conf.supybot.reply.oneToOne, to)
             else:
                 oneToOne = conf.supybot.reply.oneToOne()
@@ -665,7 +665,7 @@
         self.notice = None
         self.private = None
         self.noLengthCheck = None
-        if ircutils.isChannel(self.msg.args[0]):
+        if self.irc.isChannel(self.msg.args[0]):
             self.prefixNick = conf.get(conf.supybot.reply.withNickPrefix,
                                        self.msg.args[0])
         else:
@@ -976,7 +976,7 @@
                             pass # We'll leave it as it is.
                     mask = prefix.split('!', 1)[1]
                     self._mores[mask] = msgs
-                    public = ircutils.isChannel(msg.args[0])
+                    public = self.irc.isChannel(msg.args[0])
                     private = self.private or not public
                     self._mores[msg.nick] = (private, msgs)
                     m = reply(msg, response, to=self.to,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Limnoria-master-2019-02-23/src/ircdb.py 
new/Limnoria-master-2019-09-08/src/ircdb.py
--- old/Limnoria-master-2019-02-23/src/ircdb.py 2019-02-23 00:12:06.000000000 
+0100
+++ new/Limnoria-master-2019-09-08/src/ircdb.py 2019-09-08 14:47:05.000000000 
+0200
@@ -1175,7 +1175,13 @@
             self.value.add('-owner')
 
 conf.registerGlobalValue(conf.supybot, 'capabilities',
-    DefaultCapabilities(['-owner', '-admin', '-trusted'], """These are the
+    DefaultCapabilities([
+        '-owner', '-admin', '-trusted',
+        '-aka.add', '-aka.set', '-aka.remove',
+        '-alias.add', '-alias.remove',
+        '-scheduler.add', '-scheduler.remove',
+    ],
+    """These are the
     capabilities that are given to everyone by default.  If they are normal
     capabilities, then the user will have to have the appropriate
     anti-capability if you want to override these capabilities; if they are
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Limnoria-master-2019-02-23/src/irclib.py 
new/Limnoria-master-2019-09-08/src/irclib.py
--- old/Limnoria-master-2019-02-23/src/irclib.py        2019-02-23 
00:12:06.000000000 +0100
+++ new/Limnoria-master-2019-09-08/src/irclib.py        2019-09-08 
14:47:05.000000000 +0200
@@ -569,7 +569,7 @@
 
     def doMode(self, irc, msg):
         channel = msg.args[0]
-        if ircutils.isChannel(channel): # There can be user modes, as well.
+        if irc.isChannel(channel): # There can be user modes, as well.
             try:
                 chan = self.channels[channel]
             except KeyError:
@@ -1034,7 +1034,7 @@
     REQUEST_CAPABILITIES = set(['account-notify', 'extended-join',
         'multi-prefix', 'metadata-notify', 'account-tag',
         'userhost-in-names', 'invite-notify', 'server-time',
-        'chghost', 'batch', 'away-notify'])
+        'chghost', 'batch', 'away-notify', 'message-tags'])
 
     def _queueConnectMessages(self):
         if self.zombie:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Limnoria-master-2019-02-23/src/ircmsgs.py 
new/Limnoria-master-2019-09-08/src/ircmsgs.py
--- old/Limnoria-master-2019-02-23/src/ircmsgs.py       2019-02-23 
00:12:06.000000000 +0100
+++ new/Limnoria-master-2019-09-08/src/ircmsgs.py       2019-09-08 
14:47:05.000000000 +0200
@@ -73,7 +73,12 @@
             server_tags[tag] = None
         else:
             (key, value) = tag.split('=', 1)
-            server_tags[key] = unescape_server_tag_value(value)
+            value = unescape_server_tag_value(value)
+            if value == '':
+                # "Implementations MUST interpret empty tag values (e.g. foo=)
+                # as equivalent to missing tag values (e.g. foo)."
+                value = None
+            server_tags[key] = value
     return server_tags
 def format_server_tags(server_tags):
     parts = []
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Limnoria-master-2019-02-23/src/ircutils.py 
new/Limnoria-master-2019-09-08/src/ircutils.py
--- old/Limnoria-master-2019-02-23/src/ircutils.py      2019-02-23 
00:12:06.000000000 +0100
+++ new/Limnoria-master-2019-09-08/src/ircutils.py      2019-09-08 
14:47:05.000000000 +0200
@@ -143,7 +143,7 @@
     nick = functools.partial(isNick, strictRfc=strictRfc, nicklen=nicklen)
     return all(map(nick, s.split(',')))
 
-def isChannel(s, chantypes='#&+!', channellen=50):
+def isChannel(s, chantypes='#&!', channellen=50):
     """s => bool
     Returns True if s is a valid IRC channel name."""
     return s and \
@@ -153,13 +153,13 @@
            len(s) <= channellen and \
            len(s.split(None, 1)) == 1
 
-def areChannels(s, chantypes='#&+!',channellen=50):
+def areChannels(s, chantypes='#&!', channellen=50):
     """Like 'isChannel(x)' but for comma-separated list."""
     chan = functools.partial(isChannel, chantypes=chantypes,
             channellen=channellen)
     return all(map(chan, s.split(',')))
 
-def areReceivers(s, strictRfc=True, nicklen=None, chantypes='#&+!',
+def areReceivers(s, strictRfc=True, nicklen=None, chantypes='#&!',
         channellen=50):
     """Like 'isNick(x) or isChannel(x)' but for comma-separated list."""
     nick = functools.partial(isNick, strictRfc=strictRfc, nicklen=nicklen)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Limnoria-master-2019-02-23/src/utils/file.py 
new/Limnoria-master-2019-09-08/src/utils/file.py
--- old/Limnoria-master-2019-02-23/src/utils/file.py    2019-02-23 
00:12:06.000000000 +0100
+++ new/Limnoria-master-2019-09-08/src/utils/file.py    2019-09-08 
14:47:05.000000000 +0200
@@ -37,6 +37,16 @@
 
 from . import crypt
 
+def sanitizeName(filename):
+    """Removes / from filenames and escapes them if they are '.' or '..'."""
+    filename = filename.replace('/', '')
+    if filename == '.':
+        return '_'
+    elif filename == '..':
+        return '__'
+    else:
+        return filename
+
 def contents(filename):
     with open(filename) as fd:
         return fd.read()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Limnoria-master-2019-02-23/test/test_irclib.py 
new/Limnoria-master-2019-09-08/test/test_irclib.py
--- old/Limnoria-master-2019-02-23/test/test_irclib.py  2019-02-23 
00:12:06.000000000 +0100
+++ new/Limnoria-master-2019-09-08/test/test_irclib.py  2019-09-08 
14:47:05.000000000 +0200
@@ -35,6 +35,7 @@
 import supybot.conf as conf
 import supybot.irclib as irclib
 import supybot.ircmsgs as ircmsgs
+import supybot.ircutils as ircutils
 
 # The test framework used to provide these, but not it doesn't.  We'll add
 # messages to as we find bugs (if indeed we find bugs).
@@ -229,6 +230,10 @@
     class FakeIrc:
         nick = 'nick'
         prefix = 'nick!user@host'
+
+        def isChannel(self, s):
+            return ircutils.isChannel(s)
+
     irc = FakeIrc()
     def testKickRemovesChannel(self):
         st = irclib.IrcState()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Limnoria-master-2019-02-23/test/test_ircmsgs.py 
new/Limnoria-master-2019-09-08/test/test_ircmsgs.py
--- old/Limnoria-master-2019-02-23/test/test_ircmsgs.py 2019-02-23 
00:12:06.000000000 +0100
+++ new/Limnoria-master-2019-09-08/test/test_ircmsgs.py 2019-09-08 
14:47:05.000000000 +0200
@@ -147,6 +147,14 @@
         self.assertEqual(m.args, ('me', 'Hello'))
         self.assertEqual(str(m), s + '\n')
 
+        s = '@foo=;bar=baz;qux= ' \
+            ':[email protected] PRIVMSG me :Hello'
+        m = ircmsgs.IrcMsg(s)
+        self.assertEqual(m.server_tags, {
+            'foo': None,
+            'bar': 'baz',
+            'qux': None})
+
     def testTime(self):
         before = time.time()
         msg = ircmsgs.IrcMsg('PRIVMSG #foo :foo')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Limnoria-master-2019-02-23/test/test_ircutils.py 
new/Limnoria-master-2019-09-08/test/test_ircutils.py
--- old/Limnoria-master-2019-02-23/test/test_ircutils.py        2019-02-23 
00:12:06.000000000 +0100
+++ new/Limnoria-master-2019-09-08/test/test_ircutils.py        2019-09-08 
14:47:05.000000000 +0200
@@ -75,11 +75,13 @@
     def testIsChannel(self):
         self.failUnless(ircutils.isChannel('#'))
         self.failUnless(ircutils.isChannel('&'))
-        self.failUnless(ircutils.isChannel('+'))
+        self.failIf(ircutils.isChannel('+'))
+        self.failUnless(ircutils.isChannel('+', chantypes='#&+!'))
         self.failUnless(ircutils.isChannel('!'))
         self.failUnless(ircutils.isChannel('#foo'))
         self.failUnless(ircutils.isChannel('&foo'))
-        self.failUnless(ircutils.isChannel('+foo'))
+        self.failIf(ircutils.isChannel('+foo'))
+        self.failUnless(ircutils.isChannel('+foo', chantypes='#&+!'))
         self.failUnless(ircutils.isChannel('!foo'))
         self.failIf(ircutils.isChannel('#foo bar'))
         self.failIf(ircutils.isChannel('#foo,bar'))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Limnoria-master-2019-02-23/test/test_plugins.py 
new/Limnoria-master-2019-09-08/test/test_plugins.py
--- old/Limnoria-master-2019-02-23/test/test_plugins.py 2019-02-23 
00:12:06.000000000 +0100
+++ new/Limnoria-master-2019-09-08/test/test_plugins.py 2019-09-08 
14:47:05.000000000 +0200
@@ -29,6 +29,22 @@
 ###
 
 from supybot.test import *
+import supybot.conf as conf
 
 import supybot.irclib as irclib
 import supybot.plugins as plugins
+
+class PluginsTestCase(SupyTestCase):
+    def testMakeChannelFilename(self):
+        self.assertEqual(
+            plugins.makeChannelFilename('dir', '#foo'),
+            conf.supybot.directories.data() + '/#foo/dir')
+        self.assertEqual(
+            plugins.makeChannelFilename('dir', '#f/../oo'),
+            conf.supybot.directories.data() + '/#f..oo/dir')
+        self.assertEqual(
+            plugins.makeChannelFilename('dir', '/./'),
+            conf.supybot.directories.data() + '/_/dir')
+        self.assertEqual(
+            plugins.makeChannelFilename('dir', '/../'),
+            conf.supybot.directories.data() + '/__/dir')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Limnoria-master-2019-02-23/test/test_utils.py 
new/Limnoria-master-2019-09-08/test/test_utils.py
--- old/Limnoria-master-2019-02-23/test/test_utils.py   2019-02-23 
00:12:06.000000000 +0100
+++ new/Limnoria-master-2019-09-08/test/test_utils.py   2019-09-08 
14:47:05.000000000 +0200
@@ -504,6 +504,10 @@
         self.failUnless(utils.file.mktemp())
         self.failUnless(utils.file.mktemp())
 
+    def testSanitizeName(self):
+        self.assertEqual(utils.file.sanitizeName('#foo'), '#foo')
+        self.assertEqual(utils.file.sanitizeName('#f/../oo'), '#f..oo')
+
 
 class NetTest(SupyTestCase):
     def testEmailRe(self):


Reply via email to