mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-11-15 23:19:22 +01:00
Merge branch 'testing' of git://github.com/ProgVal/Limnoria into testing
This commit is contained in:
commit
4664d5c293
1
.gitignore
vendored
1
.gitignore
vendored
@ -23,3 +23,4 @@ supybot.egg-info/
|
||||
test-conf/
|
||||
test-data/
|
||||
test-logs/
|
||||
src/version.py
|
||||
|
80
INSTALL
Normal file
80
INSTALL
Normal file
@ -0,0 +1,80 @@
|
||||
Common
|
||||
|
||||
First things first: Supybot *requires* at least Python 2.6 and
|
||||
setuptools. There ain't no getting around it. You can get Python from
|
||||
http://www.python.org/ and setuptools from
|
||||
https://pypi.python.org/pypi/setuptools.
|
||||
|
||||
Recommended Software
|
||||
|
||||
PySQLite -- Version 1.x
|
||||
|
||||
Twisted -- Version 1.2.0 or greater
|
||||
|
||||
For more information and help on how to use Supybot, checkout
|
||||
the documents under docs/ (especially GETTING_STARTED and
|
||||
CONFIGURATION).
|
||||
|
||||
So what do you do? That depends on which operating system you're
|
||||
running. We've split this document up to address the different
|
||||
methods, so find the section for your operating system and continue
|
||||
from there.
|
||||
|
||||
UNIX/Linux/BSD
|
||||
|
||||
If you're installing Python using your distributor's packages, you may
|
||||
need a python-dev package installed, too. If you don't have a
|
||||
'/usr/lib/python2.x/distutils' directory or
|
||||
'/usr/lib/python2.x/config/Makefile' (assuming '/usr/lib/python2.x' is
|
||||
where your Python libs are installed), then you will need a python-dev
|
||||
package.
|
||||
|
||||
After you extract Supybot and cd into the supybot directory just
|
||||
created, you'll want to run (as root) 'python setup.py install'. This
|
||||
will install Supybot globally. If you need to install locally for
|
||||
whatever reason, see the notes at the end of this section. You'll then
|
||||
have several new programs installed where Python scripts are normally
|
||||
installed on your system ('/usr/bin' or '/usr/local/bin' are common on
|
||||
UNIX systems). The two that might be of particular interest to you, the
|
||||
new user, are 'supybot' and 'supybot-wizard'. The former, 'supybot', is
|
||||
the script to run an actual bot; the latter, 'supybot-wizard', is an
|
||||
in-depth wizard that provides a nice user interface for creating a
|
||||
registry file for your bot.
|
||||
|
||||
Local Install
|
||||
|
||||
You can install Supybot in a local directory by using the '--user'
|
||||
option when running 'setup.py'. E.g., 'python setup.py install
|
||||
--user' to install into your home directory. You'll now have
|
||||
a $HOME/.local/bin directory containing Supybot programs ('supybot',
|
||||
'supybot-wizard', etc.) and a $HOME/.local/lib directory containing the
|
||||
Supybot libraries.
|
||||
|
||||
Windows
|
||||
|
||||
**Note**: If you are using an IPV6 connection, you will not be able
|
||||
to run Supybot under Windows (unless Python has fixed things). Current
|
||||
versions of Python for Windows are *not* built with IPV6 support. This
|
||||
isn't expected to be fixed until Python 2.4, at the earliest.
|
||||
|
||||
Now that you have Python installed, open up a command prompt. The
|
||||
easiest way to do this is to open the run dialog (Programs -> run) and
|
||||
type "cmd" (for Windows 2000/XP/2003) or "command" (for Windows 9x). In
|
||||
order to reduce the amount of typing you need to do, I suggest adding
|
||||
Python's directory to your path. If you installed Python using the
|
||||
default settings, you would then do the following in the command prompt
|
||||
(otherwise change the path to match your settings)::
|
||||
|
||||
set PATH=C:\Python2x\;%PATH%
|
||||
|
||||
You should now be able to type 'python' to start the Python
|
||||
interpreter. Exit by pressing CTRL-Z and then Return. Now that that's
|
||||
setup, you'll want to cd into the directory that was created when you
|
||||
unzipped Supybot; I'll assume you unzipped it to 'C:\Supybot' for these
|
||||
instructions. From 'C:\Supybot', run 'python setup.py install'. This
|
||||
will install Supybot under 'C:\Python2x\'. You will now have several new
|
||||
programs installed in 'C:\Python2x\Scripts\'. The two that might be of
|
||||
particular interest to you, the new user, are 'supybot' and 'supybot-wizard'.
|
||||
The former, 'supybot', is the script to run an actual bot; the latter,
|
||||
'supybot-wizard', is an in-depth wizard that provides a nice user interface for
|
||||
creating a registry file for your bot.
|
@ -220,7 +220,7 @@ class ChannelLogger(callbacks.Plugin):
|
||||
def doNick(self, irc, msg):
|
||||
oldNick = msg.nick
|
||||
newNick = msg.args[0]
|
||||
for (channel, c) in irc.state.channels.iteritems():
|
||||
for (channel, c) in irc.state.channels.items():
|
||||
if newNick in c.users:
|
||||
self.doLog(irc, channel,
|
||||
'*** %s is now known as %s\n', oldNick, newNick)
|
||||
@ -278,7 +278,9 @@ class ChannelLogger(callbacks.Plugin):
|
||||
reason = ""
|
||||
if not isinstance(irc, irclib.Irc):
|
||||
irc = irc.getRealIrc()
|
||||
for (channel, chan) in self.lastStates[irc].channels.iteritems():
|
||||
if irc not in self.lastStates:
|
||||
return
|
||||
for (channel, chan) in self.lastStates[irc].channels.items():
|
||||
if(self.registryValue('showJoinParts', channel)):
|
||||
if msg.nick in chan.users:
|
||||
self.doLog(irc, channel,
|
||||
|
@ -239,7 +239,19 @@ class Config(callbacks.Plugin):
|
||||
s = group.help()
|
||||
if s:
|
||||
if hasattr(group, 'value') and not group._private:
|
||||
s += _(' (Current value: %s)') % group
|
||||
channel = msg.args[0]
|
||||
if irc.isChannel(channel) and \
|
||||
channel in group._children:
|
||||
globvalue = str(group)
|
||||
chanvalue = str(group.get(channel))
|
||||
if chanvalue != globvalue:
|
||||
s += _(' (Current global value: %s; '
|
||||
'current channel value: %s)') % \
|
||||
(globvalue, chanvalue)
|
||||
else:
|
||||
s += _(' (Current value: %s)') % group
|
||||
else:
|
||||
s += _(' (Current value: %s)') % group
|
||||
irc.reply(s)
|
||||
else:
|
||||
irc.reply(_('That configuration group exists, but seems to '
|
||||
|
@ -301,6 +301,10 @@ repositories = {
|
||||
'GLolol',
|
||||
'SupyPlugins',
|
||||
),
|
||||
'Iota': GithubRepository(
|
||||
'IotaSpencer',
|
||||
'supyplugins',
|
||||
),
|
||||
}
|
||||
|
||||
class PluginDownloader(callbacks.Plugin):
|
||||
|
@ -97,7 +97,7 @@ conf.registerGlobalValue(RSS, 'defaultNumberOfHeadlines',
|
||||
registry.PositiveInteger(1, _("""Indicates how many headlines an rss feed
|
||||
will output by default, if no number is provided.""")))
|
||||
conf.registerChannelValue(RSS, 'initialAnnounceHeadlines',
|
||||
registry.PositiveInteger(5, _("""Indicates how many headlines an rss feed
|
||||
registry.Integer(5, _("""Indicates how many headlines an rss feed
|
||||
will output when it is first added to announce for a channel.""")))
|
||||
conf.registerChannelValue(RSS, 'keywordWhitelist',
|
||||
registry.SpaceSeparatedSetOfStrings([], _("""Space separated list of
|
||||
|
@ -1,6 +1,6 @@
|
||||
###
|
||||
# Copyright (c) 2002-2004, Jeremiah Fincher
|
||||
# Copyright (c) 2010-2011, James McCoy
|
||||
# Copyright (c) 2010-2011, 2013, James McCoy
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
|
@ -1,5 +1,6 @@
|
||||
###
|
||||
# Copyright (c) 2002-2004, Jeremiah Fincher
|
||||
# Copyright (c) 2013, James McCoy
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@ -63,12 +64,24 @@ class ChannelDBTestCase(ChannelPluginTestCase):
|
||||
with conf.supybot.plugins.seen.showLastMessage.context(False):
|
||||
self.assertRegexp('seen any %s' % self.nick,
|
||||
'^%s was last seen[^:]*' % self.nick)
|
||||
self.assertNotError('config plugins.Seen.minimumNonWildcard 0')
|
||||
orig = conf.supybot.protocols.irc.strictRfc()
|
||||
try:
|
||||
for state in (True, False):
|
||||
conf.supybot.protocols.irc.strictRfc.setValue(state)
|
||||
for wildcard in self.wildcardTest:
|
||||
self.assertRegexp('seen any %s' % wildcard,
|
||||
'^%s was last seen' % self.nick)
|
||||
self.assertRegexp('seen any bar*', '^I haven\'t seen anyone matching')
|
||||
finally:
|
||||
conf.supybot.protocols.irc.strictRfc.setValue(orig)
|
||||
|
||||
def testSeen(self):
|
||||
self.irc.feedMsg(ircmsgs.join(self.channel, self.irc.nick,
|
||||
prefix=self.prefix))
|
||||
self.assertNotError('seen last')
|
||||
self.assertNotError('list')
|
||||
self.assertNotError('config plugins.Seen.minimumNonWildcard 2')
|
||||
self.assertError('seen *')
|
||||
self.assertNotError('seen %s' % self.nick)
|
||||
m = self.assertNotError('seen %s' % self.nick.upper())
|
||||
@ -76,10 +89,16 @@ class ChannelDBTestCase(ChannelPluginTestCase):
|
||||
self.assertRegexp('seen user %s' % self.nick,
|
||||
'^%s was last seen' % self.nick)
|
||||
self.assertNotError('config plugins.Seen.minimumNonWildcard 0')
|
||||
for wildcard in self.wildcardTest:
|
||||
self.assertRegexp('seen %s' % wildcard,
|
||||
'^%s was last seen' % self.nick)
|
||||
self.assertRegexp('seen bar*', '^I haven\'t seen anyone matching')
|
||||
orig = conf.supybot.protocols.irc.strictRfc()
|
||||
try:
|
||||
for state in (True, False):
|
||||
conf.supybot.protocols.irc.strictRfc.setValue(state)
|
||||
for wildcard in self.wildcardTest:
|
||||
self.assertRegexp('seen %s' % wildcard,
|
||||
'^%s was last seen' % self.nick)
|
||||
self.assertRegexp('seen bar*', '^I haven\'t seen anyone matching')
|
||||
finally:
|
||||
conf.supybot.protocols.irc.strictRfc.setValue(orig)
|
||||
|
||||
def testSeenNoUser(self):
|
||||
self.irc.feedMsg(ircmsgs.join(self.channel, self.irc.nick,
|
||||
|
@ -114,7 +114,6 @@ def catch_web_errors(f):
|
||||
|
||||
class Web(callbacks.PluginRegexp):
|
||||
"""Add the help for "@help Web" here."""
|
||||
threaded = True
|
||||
regexps = ['titleSnarfer']
|
||||
|
||||
@fetch_sandbox
|
||||
|
3
setup.py
3
setup.py
@ -212,7 +212,8 @@ setup(
|
||||
url='https://github.com/ProgVal/Limnoria',
|
||||
author_email='progval+limnoria@progval.net',
|
||||
download_url='http://builds.progval.net/limnoria/',
|
||||
description='A modified version of Supybot (an IRC bot)',
|
||||
description='A modified version of Supybot (an IRC bot and framework)',
|
||||
platforms=['linux', 'linux2', 'win32', 'cygwin', 'darwin'],
|
||||
long_description=normalizeWhitespace("""A robust, full-featured Python IRC
|
||||
bot with a clean and flexible plugin API. Equipped with a complete ACL
|
||||
system for specifying user permissions with as much as per-command
|
||||
|
@ -336,16 +336,14 @@ def getNetworkIrc(irc, msg, args, state, errorIfNoMatch=False):
|
||||
state.args.append(irc)
|
||||
|
||||
def getHaveVoice(irc, msg, args, state, action=_('do that')):
|
||||
if not state.channel:
|
||||
getChannel(irc, msg, args, state)
|
||||
getChannel(irc, msg, args, state)
|
||||
if state.channel not in irc.state.channels:
|
||||
state.error(_('I\'m not even in %s.') % state.channel, Raise=True)
|
||||
if not irc.state.channels[state.channel].isVoice(irc.nick):
|
||||
state.error(_('I need to be voiced to %s.') % action, Raise=True)
|
||||
|
||||
def getHaveVoicePlus(irc, msg, args, state, action=_('do that')):
|
||||
if not state.channel:
|
||||
getChannel(irc, msg, args, state)
|
||||
getChannel(irc, msg, args, state)
|
||||
if state.channel not in irc.state.channels:
|
||||
state.error(_('I\'m not even in %s.') % state.channel, Raise=True)
|
||||
if not irc.state.channels[state.channel].isVoicePlus(irc.nick):
|
||||
@ -354,16 +352,14 @@ def getHaveVoicePlus(irc, msg, args, state, action=_('do that')):
|
||||
Raise=True)
|
||||
|
||||
def getHaveHalfop(irc, msg, args, state, action=_('do that')):
|
||||
if not state.channel:
|
||||
getChannel(irc, msg, args, state)
|
||||
getChannel(irc, msg, args, state)
|
||||
if state.channel not in irc.state.channels:
|
||||
state.error(_('I\'m not even in %s.') % state.channel, Raise=True)
|
||||
if not irc.state.channels[state.channel].isHalfop(irc.nick):
|
||||
state.error(_('I need to be halfopped to %s.') % action, Raise=True)
|
||||
|
||||
def getHaveHalfopPlus(irc, msg, args, state, action=_('do that')):
|
||||
if not state.channel:
|
||||
getChannel(irc, msg, args, state)
|
||||
getChannel(irc, msg, args, state)
|
||||
if state.channel not in irc.state.channels:
|
||||
state.error(_('I\'m not even in %s.') % state.channel, Raise=True)
|
||||
if not irc.state.channels[state.channel].isHalfopPlus(irc.nick):
|
||||
@ -372,8 +368,7 @@ def getHaveHalfopPlus(irc, msg, args, state, action=_('do that')):
|
||||
Raise=True)
|
||||
|
||||
def getHaveOp(irc, msg, args, state, action=_('do that')):
|
||||
if not state.channel:
|
||||
getChannel(irc, msg, args, state)
|
||||
getChannel(irc, msg, args, state)
|
||||
if state.channel not in irc.state.channels:
|
||||
state.error(_('I\'m not even in %s.') % state.channel, Raise=True)
|
||||
if not irc.state.channels[state.channel].isOp(irc.nick):
|
||||
@ -400,8 +395,7 @@ def getHostmask(irc, msg, args, state):
|
||||
|
||||
def getBanmask(irc, msg, args, state):
|
||||
getHostmask(irc, msg, args, state)
|
||||
if not state.channel:
|
||||
getChannel(irc, msg, args, state)
|
||||
getChannel(irc, msg, args, state)
|
||||
channel = state.channel
|
||||
banmaskstyle = conf.supybot.protocols.irc.banmask
|
||||
state.args[-1] = banmaskstyle.makeBanmask(state.args[-1])
|
||||
@ -477,6 +471,8 @@ def getSeenNick(irc, msg, args, state, errmsg=None):
|
||||
state.error(errmsg, Raise=True)
|
||||
|
||||
def getChannel(irc, msg, args, state):
|
||||
if state.channel:
|
||||
return
|
||||
if args and irc.isChannel(args[0]):
|
||||
channel = args.pop(0)
|
||||
elif irc.isChannel(msg.args[0]):
|
||||
@ -508,8 +504,7 @@ def getChannelDb(irc, msg, args, state, **kwargs):
|
||||
state.args.append(channel)
|
||||
|
||||
def inChannel(irc, msg, args, state):
|
||||
if not state.channel:
|
||||
getChannel(irc, msg, args, state)
|
||||
getChannel(irc, msg, args, state)
|
||||
if state.channel not in irc.state.channels:
|
||||
state.error(_('I\'m not in %s.') % state.channel, Raise=True)
|
||||
|
||||
@ -564,8 +559,7 @@ def getChannelOrGlobal(irc, msg, args, state):
|
||||
state.args.append(channel)
|
||||
|
||||
def checkChannelCapability(irc, msg, args, state, cap):
|
||||
if not state.channel:
|
||||
getChannel(irc, msg, args, state)
|
||||
getChannel(irc, msg, args, state)
|
||||
cap = ircdb.canonicalCapability(cap)
|
||||
cap = ircdb.makeChannelCapability(state.channel, cap)
|
||||
if not ircdb.checkCapability(msg.prefix, cap):
|
||||
|
@ -361,15 +361,15 @@ class Favicon(SupyHTTPServerCallback):
|
||||
file_path = conf.supybot.servers.http.favicon()
|
||||
found = False
|
||||
if file_path:
|
||||
response = None
|
||||
try:
|
||||
icon = open(file_path, 'r')
|
||||
found = True
|
||||
icon = open(file_path, 'rb')
|
||||
response = icon.read()
|
||||
except IOError:
|
||||
pass
|
||||
finally:
|
||||
icon.close()
|
||||
if found:
|
||||
response = icon.read()
|
||||
if response is not None:
|
||||
filename = file_path.rsplit(os.sep, 1)[1]
|
||||
if '.' in filename:
|
||||
ext = filename.rsplit('.', 1)[1]
|
||||
|
@ -209,7 +209,10 @@ class ValidLogLevel(registry.String):
|
||||
def set(self, s):
|
||||
s = s.upper()
|
||||
try:
|
||||
level = logging._levelNames[s]
|
||||
try:
|
||||
level = logging._levelNames[s]
|
||||
except AttributeError:
|
||||
level = logging._nameToLevel[s]
|
||||
except KeyError:
|
||||
try:
|
||||
level = int(s)
|
||||
|
Loading…
Reference in New Issue
Block a user