Update to Python 3 / Limnoria plugin

This is a run of "2to3" over these files, and minor updates to the
MeetBot/__init__.py that make it work with Limnoria.

Change-Id: I1083cdf095814af3d84b294dc9ca9a63eb97ac3c
This commit is contained in:
Ian Wienand 2021-06-01 12:11:38 +10:00
parent eec003e3e3
commit 1a35647ad5
7 changed files with 65 additions and 54 deletions

View File

@ -35,6 +35,8 @@ here. This should describe *what* the plugin does.
import supybot
import supybot.world as world
import sys
import importlib
# 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.
@ -50,14 +52,21 @@ __contributors__ = {}
# This is a url where the most recent plugin package can be downloaded.
__url__ = '' # 'http://supybot.com/Members/yourname/MeetBot/download'
import config
import plugin
reload(plugin) # In case we're being reloaded.
from . import config
from . import plugin
if sys.version_info >= (3, 4):
from importlib import reload
else:
from imp import reload
# In case we're being reloaded.
importlib.reload(config)
importlib.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:
import test
from . import test
Class = plugin.Class
configure = config.configure

View File

@ -37,10 +37,11 @@ import supybot.ircmsgs as ircmsgs
import time
import ircmeeting.meeting as meeting
import supybotconfig
from . import supybotconfig
import importlib
# Because of the way we override names, we need to reload these in order.
meeting = reload(meeting)
supybotconfig = reload(supybotconfig)
meeting = importlib.reload(meeting)
supybotconfig = importlib.reload(supybotconfig)
if supybotconfig.is_supybotconfig_enabled(meeting.Config):
supybotconfig.setup_config(meeting.Config)
@ -148,8 +149,8 @@ class MeetBot(callbacks.Plugin):
M.addrawline(nick, payload)
except:
import traceback
print traceback.print_exc()
print "(above exception in outFilter, ignoring)"
print(traceback.print_exc())
print("(above exception in outFilter, ignoring)")
return msg
# These are admin commands, for use by the bot owner when there
@ -170,7 +171,7 @@ class MeetBot(callbacks.Plugin):
Save all currently active meetings."""
numSaved = 0
for M in meeting_cache.iteritems():
for M in meeting_cache.items():
M.config.save()
irc.reply("Saved %d meetings."%numSaved)
savemeetings = wrap(savemeetings, ['admin'])

View File

@ -60,14 +60,14 @@ class WriterMap(registry.String):
writer_map[ext] = getattr(writers, writer)
self.setValue(writer_map)
def setValue(self, writer_map):
for e, w in writer_map.iteritems():
for e, w in writer_map.items():
if not hasattr(w, "format"):
raise ValueError("Writer %s must have method .format()"%
w.__name__)
self.value = writer_map
def __str__(self):
writers_string = [ ]
for ext, w in self.value.iteritems():
for ext, w in self.value.items():
name = w.__name__
writers_string.append("%s:%s"%(name, ext))
return " ".join(writers_string)
@ -81,7 +81,7 @@ class SupybotConfigProxy(object):
# We need to call the __init__ *after* we have rebound the
# method to get variables from the config proxy.
old_init = self.__C.__init__
new_init = types.MethodType(old_init.im_func, self, old_init.im_class)
new_init = types.MethodType(old_init.__func__, self, old_init.__self__.__class__)
new_init(*args, **kwargs)
def __getattr__(self, attrname):
@ -91,7 +91,7 @@ class SupybotConfigProxy(object):
if attrname in settable_attributes:
M = self.M
value = M._registryValue(attrname, channel=M.channel)
if not isinstance(value, (str, unicode)):
if not isinstance(value, str):
return value
# '.' is used to mean "this is not set, use the default
# value from the python config class.
@ -122,7 +122,7 @@ class SupybotConfigProxy(object):
# values). This will slow things down a little bit, but
# that's just the cost of duing business.
if hasattr(value, 'im_func'):
return types.MethodType(value.im_func, self, value.im_class)
return types.MethodType(value.__func__, self, value.__self__.__class__)
return value
@ -145,7 +145,7 @@ def setup_config(OriginalConfig):
continue
attr = getattr(OriginalConfig, attrname)
# Don't configure attributes that aren't strings.
if isinstance(attr, (str, unicode)):
if isinstance(attr, str):
attr = attr.replace('\n', '\\n')
# For a global value: conf.registerGlobalValue and remove the
# channel= option from registryValue call above.

View File

@ -69,12 +69,12 @@ class MeetBotTestCase(ChannelPluginTestCase):
groups = re.search(test[0], line).groups()
# Output pattern depends on input pattern
if isinstance(test[1], int):
print groups[test[1]-1], reply
print(groups[test[1]-1], reply)
assert re.search(re.escape(groups[test[1]-1]), reply),\
'line "%s" gives output "%s"'%(line, reply)
# Just match the given pattern.
else:
print test[1], reply
print(test[1], reply)
assert re.search(test[1], reply.decode('utf-8')), \
'line "%s" gives output "%s"'%(line, reply)

View File

@ -33,7 +33,7 @@ import os
import re
import time
import writers
from . import writers
#from writers import html, rst
import itertools
@ -84,7 +84,7 @@ class _BaseItem(object):
return replacements
def template(self, M, escapewith):
template = { }
for k,v in self.get_replacements(M, escapewith).iteritems():
for k,v in self.get_replacements(M, escapewith).items():
if k not in ('itemtype', 'line', 'topic',
'url', 'url_quoteescaped',
'nick', 'time', 'link', 'anchor'):

View File

@ -35,10 +35,11 @@ import re
import stat
import textwrap
import writers
import items
reload(writers)
reload(items)
from . import writers
from . import items
import importlib
importlib.reload(writers)
importlib.reload(items)
__version__ = "0.1.4"
@ -132,14 +133,14 @@ class Config(object):
self.M = M
self.writers = { }
# Update config values with anything we may have
for k,v in extraConfig.iteritems():
for k,v in extraConfig.items():
setattr(self, k, v)
if hasattr(self, "init_hook"):
self.init_hook()
if writeRawLog:
self.writers['.log.txt'] = writers.TextLog(self.M)
for extension, writer in self.writer_map.iteritems():
for extension, writer in self.writer_map.items():
self.writers[extension] = writer(self.M)
self.safeMode = safeMode
def filename(self, url=False):
@ -219,9 +220,9 @@ class Config(object):
# If it doesn't, then it's assumed that the write took
# care of writing (or publishing or emailing or wikifying)
# it itself.
if isinstance(text, unicode):
if isinstance(text, str):
text = self.enc(text)
if isinstance(text, (str, unicode)):
if isinstance(text, str):
# Have a way to override saving, so no disk files are written.
if getattr(self, "dontSave", False):
pass
@ -281,7 +282,7 @@ else:
# First source of config: try just plain importing it
try:
import meetingLocalConfig
meetingLocalConfig = reload(meetingLocalConfig)
meetingLocalConfig = importlib.reload(meetingLocalConfig)
if hasattr(meetingLocalConfig, 'Config'):
LocalConfig = meetingLocalConfig.Config
except ImportError:
@ -291,7 +292,7 @@ else:
fname = os.path.join(dirname, "meetingLocalConfig.py")
if os.access(fname, os.F_OK):
meetingLocalConfig = { }
execfile(fname, meetingLocalConfig)
exec(compile(open(fname, "rb").read(), fname, 'exec'), meetingLocalConfig)
LocalConfig = meetingLocalConfig["Config"]
break
if LocalConfig is not None:
@ -491,9 +492,9 @@ class MeetingCommands(object):
m = 'Voted on "%s?" Results are' % self._voteTopic
self.reply(m)
self.do_showvote(**kwargs)
for k,s in self._votes.iteritems():
vote = self._voteOptions[map(unicode.lower,
self._voteOptions).index(k)]
for k,s in self._votes.items():
vote = self._voteOptions[list(map(str.lower,
self._voteOptions)).index(k)]
m += ", %s: %s" % (vote, len(s))
m = items.Vote(nick=nick, line=m, **kwargs)
self.additem(m)
@ -505,7 +506,7 @@ class MeetingCommands(object):
"""Vote for specific voting topic option."""
if self._voteTopic is None: return
vote = line.lower()
if vote in map(unicode.lower, self._voteOptions):
if vote in list(map(str.lower, self._voteOptions)):
oldvote = self._voters.get(nick)
if oldvote is not None:
self._votes[oldvote].remove(nick)
@ -520,13 +521,13 @@ class MeetingCommands(object):
def do_showvote(self, **kwargs):
"""Show intermediate vote results."""
if self._voteTopic is None: return
for k, s in self._votes.iteritems():
for k, s in self._votes.items():
# Attempt to print all the names while obeying the 512 character
# limit. Would probably be better to calculate message overhead and
# determine wraps()s width argument based on that.
ms = textwrap.wrap(", ".join(s), 400)
vote = self._voteOptions[map(unicode.lower,
self._voteOptions).index(k)]
vote = self._voteOptions[list(map(str.lower,
self._voteOptions)).index(k)]
for m2 in ms:
m1 = "%s (%s): " % (vote, len(s))
self.reply(m1 + m2)
@ -584,13 +585,13 @@ class Meeting(MeetingCommands, object):
if hasattr(self, '_sendReply') and not self._lurk:
self._sendReply(self.config.enc(x))
else:
print "REPLY:", self.config.enc(x)
print("REPLY:", self.config.enc(x))
def topic(self, x):
"""Set the topic in the IRC channel."""
if hasattr(self, '_setTopic') and not self._lurk:
self._setTopic(self.config.enc(x))
else:
print "TOPIC:", self.config.enc(x)
print("TOPIC:", self.config.enc(x))
def settopic(self):
"The actual code to set the topic"
if self._meetingTopic:
@ -736,7 +737,7 @@ if __name__ == '__main__':
filename = m.group(1)
else:
filename = os.path.splitext(fname)[0]
print 'Saving to:', filename
print('Saving to:', filename)
channel = '#'+os.path.basename(sys.argv[2]).split('.')[0]
M = Meeting(channel=channel, owner=None,
@ -760,5 +761,5 @@ if __name__ == '__main__':
M.addline(nick, "ACTION "+line, time_=time_)
#M.save() # should be done by #endmeeting in the logs!
else:
print 'Command "%s" not found.'%sys.argv[1]
print('Command "%s" not found.'%sys.argv[1])

View File

@ -38,7 +38,7 @@ import time
# Needed for testing with isinstance() for properly writing.
#from items import Topic, Action
import items
from . import items
# Data sanitizing for various output methods
def html(text):
@ -73,7 +73,7 @@ def makeNickRE(nick):
return re.compile('\\b'+re.escape(nick)+'\\b', re.IGNORECASE)
def MeetBotVersion():
import meeting
from . import meeting
if hasattr(meeting, '__version__'):
return ' '+meeting.__version__
else:
@ -121,12 +121,12 @@ class _BaseWriter(object):
'MeetBotVersion':MeetBotVersion(),
}
def iterNickCounts(self):
nicks = [ (n,c) for (n,c) in self.M.attendees.iteritems() ]
nicks = [ (n,c) for (n,c) in self.M.attendees.items() ]
nicks.sort(key=lambda x: x[1], reverse=True)
return nicks
def iterActionItemsNick(self):
for nick in sorted(self.M.attendees.keys(), key=lambda x: x.lower()):
for nick in sorted(list(self.M.attendees.keys()), key=lambda x: x.lower()):
nick_re = makeNickRE(nick)
def nickitems(nick_re):
for m in self.M.minutes:
@ -330,12 +330,12 @@ class _CSSmanager(object):
css_head = ('''<link rel="stylesheet" type="text/css" '''
'''href="%s">'''%cssfile)
return css_head
except Exception, exc:
except Exception as exc:
if not self.M.config.safeMode:
raise
import traceback
traceback.print_exc()
print "(exception above ignored, continuing)"
print("(exception above ignored, continuing)")
try:
css_fname = os.path.join(os.path.dirname(__file__),
'css-'+name+'-default.css')
@ -471,9 +471,9 @@ class HTMLlog2(_BaseWriter, _CSSmanager):
'nick':html(m.group('nick')),
'line':html(m.group('line')),})
continue
print l
print m.groups()
print "**error**", l
print(l)
print(m.groups())
print("**error**", l)
css = self.getCSS(name='log')
return html_template%{'pageTitle':"%s log"%html(M.channel),
@ -850,7 +850,7 @@ class ReST(_BaseWriter):
# Action Items, by person (This could be made lots more efficient)
ActionItemsPerson = [ ]
for nick in sorted(M.attendees.keys(), key=lambda x: x.lower()):
for nick in sorted(list(M.attendees.keys()), key=lambda x: x.lower()):
nick_re = makeNickRE(nick)
headerPrinted = False
for m in M.minutes:
@ -956,7 +956,7 @@ class Text(_BaseWriter):
ActionItemsPerson = [ ]
ActionItemsPerson.append(self.heading('Action items, by person'))
numberAssigned = 0
for nick in sorted(M.attendees.keys(), key=lambda x: x.lower()):
for nick in sorted(list(M.attendees.keys()), key=lambda x: x.lower()):
nick_re = makeNickRE(nick)
headerPrinted = False
for m in M.minutes:
@ -1084,7 +1084,7 @@ class MediaWiki(_BaseWriter):
ActionItemsPerson = [ ]
ActionItemsPerson.append(self.heading('Action items, by person'))
numberAssigned = 0
for nick in sorted(M.attendees.keys(), key=lambda x: x.lower()):
for nick in sorted(list(M.attendees.keys()), key=lambda x: x.lower()):
nick_re = makeNickRE(nick)
headerPrinted = False
for m in M.minutes:
@ -1190,7 +1190,7 @@ class PmWiki(MediaWiki, object):
return '%s %s\n'%('!'*(level+1), name)
def replacements(self):
#repl = super(PmWiki, self).replacements(self) # fails, type checking
repl = MediaWiki.replacements.im_func(self)
repl = MediaWiki.replacements.__func__(self)
repl['pageTitleHeading'] = self.heading(repl['pageTitle'],level=0)
return repl