Changeset View
Standalone View
wallace/modules.py
Show All 40 Lines | |||||
from pykolab import constants | from pykolab import constants | ||||
from pykolab.translate import _ | from pykolab.translate import _ | ||||
log = pykolab.getLogger('pykolab.wallace') | log = pykolab.getLogger('pykolab.wallace') | ||||
conf = pykolab.getConf() | conf = pykolab.getConf() | ||||
modules = {} | modules = {} | ||||
def __init__(): | def __init__(): | ||||
Lint: PEP8 E302: expected 2 blank lines, found 1 | |||||
# We only want the base path | # We only want the base path | ||||
modules_base_path = os.path.dirname(__file__) | modules_base_path = os.path.dirname(__file__) | ||||
for modules_path, dirnames, filenames in os.walk(modules_base_path): | for modules_path, dirnames, filenames in os.walk(modules_base_path): | ||||
if not modules_path == modules_base_path: | if not modules_path == modules_base_path: | ||||
continue | continue | ||||
for filename in filenames: | for filename in filenames: | ||||
if filename.startswith('module_') and filename.endswith('.py'): | if filename.startswith('module_') and filename.endswith('.py'): | ||||
module_name = filename.replace('.py','') | module_name = filename.replace('.py','') | ||||
Lint: PEP8 E231 missing whitespace after ',' Lint: PEP8 E231: missing whitespace after ',' | |||||
name = module_name.replace('module_', '') | name = module_name.replace('module_', '') | ||||
#print "exec(\"from %s import __init__ as %s_register\"" % (module_name,name) | #print "exec(\"from %s import __init__ as %s_register\"" % (module_name,name) | ||||
Lint: PEP8 E265 block comment should start with '# ' Lint: PEP8 E265: block comment should start with '# ' | |||||
Lint: PEP8 E501 line too long (93 > 79 characters) Lint: PEP8 E501: line too long (93 > 79 characters) | |||||
exec("from %s import __init__ as %s_register" % (module_name, name)) | exec("from %s import __init__ as %s_register" % (module_name, name)) | ||||
Lint: PEP8 E501 line too long (84 > 79 characters) Lint: PEP8 E501: line too long (84 > 79 characters) | |||||
exec("%s_register()" % (name)) | exec("%s_register()" % (name)) | ||||
for dirname in dirnames: | for dirname in dirnames: | ||||
register_group(modules_path, dirname) | register_group(modules_path, dirname) | ||||
def list_modules(*args, **kw): | def list_modules(*args, **kw): | ||||
Lint: PEP8 E302 expected 2 blank lines, found 1 Lint: PEP8 E302: expected 2 blank lines, found 1 | |||||
""" | """ | ||||
List modules | List modules | ||||
""" | """ | ||||
__modules = {} | __modules = {} | ||||
for module in modules.keys(): | for module in modules.keys(): | ||||
if isinstance(module, tuple): | if isinstance(module, tuple): | ||||
module_group, module = module | module_group, module = module | ||||
__modules[module_group] = { | __modules[module_group] = { | ||||
module: modules[(module_group,module)] | module: modules[(module_group,module)] | ||||
Lint: PEP8 E231 missing whitespace after ',' Lint: PEP8 E231: missing whitespace after ',' | |||||
} | } | ||||
else: | else: | ||||
__modules[module] = modules[module] | __modules[module] = modules[module] | ||||
_modules = __modules.keys() | _modules = __modules.keys() | ||||
_modules.sort() | _modules.sort() | ||||
for _module in _modules: | for _module in _modules: | ||||
if __modules[_module].has_key('function'): | if __modules[_module].has_key('function'): | ||||
# This is a top-level module | # This is a top-level module | ||||
if not __modules[_module]['description'] == None: | if not __modules[_module]['description'] == None: | ||||
Lint: PEP8 E711 comparison to None should be 'if cond is None:' Lint: PEP8 E711: comparison to None should be 'if cond is None:' | |||||
print "%-25s - %s" % (_module.replace('_','-'),__modules[_module]['description']) | print "%-25s - %s" % (_module.replace('_','-'),__modules[_module]['description']) | ||||
Lint: PEP8 E231 missing whitespace after ',' Lint: PEP8 E231: missing whitespace after ',' | |||||
Lint: PEP8 E231 missing whitespace after ',' Lint: PEP8 E231: missing whitespace after ',' | |||||
Lint: PEP8 E501 line too long (97 > 79 characters) Lint: PEP8 E501: line too long (97 > 79 characters) | |||||
else: | else: | ||||
print "%-25s" % (_module.replace('_','-')) | print "%-25s" % (_module.replace('_','-')) | ||||
Lint: PEP8 E231 missing whitespace after ',' Lint: PEP8 E231: missing whitespace after ',' | |||||
for _module in _modules: | for _module in _modules: | ||||
if not __modules[_module].has_key('function'): | if not __modules[_module].has_key('function'): | ||||
# This is a nested module | # This is a nested module | ||||
print "\n" + _("Module Group: %s") % (_module) + "\n" | print "\n" + _("Module Group: %s") % (_module) + "\n" | ||||
___modules = __modules[_module].keys() | ___modules = __modules[_module].keys() | ||||
___modules.sort() | ___modules.sort() | ||||
for __module in ___modules: | for __module in ___modules: | ||||
if not __modules[_module][__module]['description'] == None: | if not __modules[_module][__module]['description'] == None: | ||||
Lint: PEP8 E711 comparison to None should be 'if cond is None:' Lint: PEP8 E711: comparison to None should be 'if cond is None:' | |||||
print "%-4s%-21s - %s" % ('',__module.replace('_','-'),__modules[_module][__module]['description']) | print "%-4s%-21s - %s" % ('',__module.replace('_','-'),__modules[_module][__module]['description']) | ||||
Lint: PEP8 E231 missing whitespace after ',' Lint: PEP8 E231: missing whitespace after ',' | |||||
Lint: PEP8 E231 missing whitespace after ',' Lint: PEP8 E231: missing whitespace after ',' | |||||
Lint: PEP8 E231 missing whitespace after ',' Lint: PEP8 E231: missing whitespace after ',' | |||||
Lint: PEP8 E501 line too long (119 > 79 characters) Lint: PEP8 E501: line too long (119 > 79 characters) | |||||
else: | else: | ||||
print "%-4s%-21s" % ('',__module.replace('_','-')) | print "%-4s%-21s" % ('',__module.replace('_','-')) | ||||
Lint: PEP8 E231 missing whitespace after ',' Lint: PEP8 E231: missing whitespace after ',' | |||||
Lint: PEP8 E231 missing whitespace after ',' Lint: PEP8 E231: missing whitespace after ',' | |||||
def execute(name, *args, **kw): | def execute(name, *args, **kw): | ||||
Lint: PEP8 E302 expected 2 blank lines, found 1 Lint: PEP8 E302: expected 2 blank lines, found 1 | |||||
if not modules.has_key(name): | if not modules.has_key(name): | ||||
log.error(_("No such module %r in modules %r (1).") % (name, modules)) | log.error(_("No such module %r in modules %r (1).") % (name, modules)) | ||||
sys.exit(1) | sys.exit(1) | ||||
if not modules[name].has_key('function') and \ | if not modules[name].has_key('function') and \ | ||||
not modules[name].has_key('group'): | not modules[name].has_key('group'): | ||||
Lint: PEP8 E125 continuation line with same indent as next logical line Lint: PEP8 E125: continuation line with same indent as next logical line | |||||
log.error(_("No such module %r in modules %r (2).") %(name, modules)) | log.error(_("No such module %r in modules %r (2).") %(name, modules)) | ||||
Lint: PEP8 E225 missing whitespace around operator Lint: PEP8 E225: missing whitespace around operator | |||||
sys.exit(1) | sys.exit(1) | ||||
try: | |||||
return modules[name]['function'](*args, **kw) | return modules[name]['function'](*args, **kw) | ||||
except Exception, errmsg: | |||||
log.error(_("Unknown error occurred; %r") % (errmsg)) | |||||
log.error("%r" % (traceback.format_exc())) | |||||
vanmeeuwenUnsubmitted Done Inline ActionsPlease remember to import traceback vanmeeuwen: Please remember to import traceback | |||||
machniakAuthorUnsubmitted Not Done Inline ActionsIt is already imported. machniak: It is already imported. | |||||
vanmeeuwenUnsubmitted Not Done Inline ActionsAgreed, sorry. vanmeeuwen: Agreed, sorry. | |||||
def heartbeat(name, *args, **kw): | def heartbeat(name, *args, **kw): | ||||
Lint: PEP8 E302 expected 2 blank lines, found 1 Lint: PEP8 E302: expected 2 blank lines, found 1 | |||||
if not modules.has_key(name): | if not modules.has_key(name): | ||||
log.warning(_("No such module %r in modules %r (1).") % (name, modules)) | log.warning(_("No such module %r in modules %r (1).") % (name, modules)) | ||||
Lint: PEP8 E501 line too long (80 > 79 characters) Lint: PEP8 E501: line too long (80 > 79 characters) | |||||
if modules[name].has_key('heartbeat'): | if modules[name].has_key('heartbeat'): | ||||
return modules[name]['heartbeat'](*args, **kw) | return modules[name]['heartbeat'](*args, **kw) | ||||
def _sendmail(sender, recipients, msg): | def _sendmail(sender, recipients, msg): | ||||
Lint: PEP8 E302 expected 2 blank lines, found 1 Lint: PEP8 E302: expected 2 blank lines, found 1 | |||||
# NOTE: Use "127.0.0.1" here for IPv6 (see also the service | # NOTE: Use "127.0.0.1" here for IPv6 (see also the service | ||||
# definition in master.cf). | # definition in master.cf). | ||||
smtp = smtplib.SMTP("127.0.0.1", 10027) | smtp = smtplib.SMTP("127.0.0.1", 10027) | ||||
if conf.debuglevel > 8: | if conf.debuglevel > 8: | ||||
smtp.set_debuglevel(True) | smtp.set_debuglevel(True) | ||||
# Not an infinite loop | # Not an infinite loop | ||||
Show All 30 Lines | while True: | ||||
log.error("SMTP Sender Refused, %r" % (errmsg)) | log.error("SMTP Sender Refused, %r" % (errmsg)) | ||||
except Exception, errmsg: | except Exception, errmsg: | ||||
log.error(_("Unknown error occurred; %r") % (errmsg)) | log.error(_("Unknown error occurred; %r") % (errmsg)) | ||||
log.error("%r" % (traceback.format_exc())) | log.error("%r" % (traceback.format_exc())) | ||||
return False | return False | ||||
def cb_action_HOLD(module, filepath): | def cb_action_HOLD(module, filepath): | ||||
Lint: PEP8 E302 expected 2 blank lines, found 1 Lint: PEP8 E302: expected 2 blank lines, found 1 | |||||
log.info(_("Holding message in queue for manual review (%s by %s)") % (filepath, module)) | log.info(_("Holding message in queue for manual review (%s by %s)") % (filepath, module)) | ||||
Lint: PEP8 E501 line too long (93 > 79 characters) Lint: PEP8 E501: line too long (93 > 79 characters) | |||||
def cb_action_DEFER(module, filepath): | def cb_action_DEFER(module, filepath): | ||||
Lint: PEP8 E302 expected 2 blank lines, found 1 Lint: PEP8 E302: expected 2 blank lines, found 1 | |||||
log.info(_("Deferring message in %s (by module %s)") % (filepath, module)) | log.info(_("Deferring message in %s (by module %s)") % (filepath, module)) | ||||
# parse message headers | # parse message headers | ||||
message = Parser().parse(open(filepath, 'r'), True) | message = Parser().parse(open(filepath, 'r'), True) | ||||
internal_time = parsedate_tz(message.__getitem__('Date')) | internal_time = parsedate_tz(message.__getitem__('Date')) | ||||
internal_time = time.mktime(internal_time[:9]) + internal_time[9] | internal_time = time.mktime(internal_time[:9]) + internal_time[9] | ||||
now_time = time.time() | now_time = time.time() | ||||
delta = now_time - internal_time | delta = now_time - internal_time | ||||
log.debug(_("The time when the message was sent: %r") % (internal_time), level=8) | log.debug(_("The time when the message was sent: %r") % (internal_time), level=8) | ||||
Lint: PEP8 E501 line too long (85 > 79 characters) Lint: PEP8 E501: line too long (85 > 79 characters) | |||||
log.debug(_("The time now: %r") % (now_time), level=8) | log.debug(_("The time now: %r") % (now_time), level=8) | ||||
log.debug(_("The time delta: %r") % (delta), level=8) | log.debug(_("The time delta: %r") % (delta), level=8) | ||||
if delta > 432000: | if delta > 432000: | ||||
# TODO: Send NDR back to user | # TODO: Send NDR back to user | ||||
log.debug(_("Message in file %s older then 5 days, deleting") % (filepath), level=8) | log.debug(_("Message in file %s older then 5 days, deleting") % (filepath), level=8) | ||||
Lint: PEP8 E501 line too long (92 > 79 characters) Lint: PEP8 E501: line too long (92 > 79 characters) | |||||
os.unlink(filepath) | os.unlink(filepath) | ||||
# Alternative method is file age. | # Alternative method is file age. | ||||
#Date sent(/var/spool/pykolab/wallace/optout/DEFER/tmpIv7pDl): 'Thu, 08 Mar 2012 11:51:03 +0000' | #Date sent(/var/spool/pykolab/wallace/optout/DEFER/tmpIv7pDl): 'Thu, 08 Mar 2012 11:51:03 +0000' | ||||
Lint: PEP8 E265 block comment should start with '# ' Lint: PEP8 E265: block comment should start with '# ' | |||||
Lint: PEP8 E501 line too long (100 > 79 characters) Lint: PEP8 E501: line too long (100 > 79 characters) | |||||
#(2012, 3, 8, 11, 51, 3, 0, 1, -1) | #(2012, 3, 8, 11, 51, 3, 0, 1, -1) | ||||
Lint: PEP8 E265 block comment should start with '# ' Lint: PEP8 E265: block comment should start with '# ' | |||||
# YYYY M D H m s weekday, yearday | # YYYY M D H m s weekday, yearday | ||||
#log.debug(datetime.datetime(*), level=8) | #log.debug(datetime.datetime(*), level=8) | ||||
Lint: PEP8 E265 block comment should start with '# ' Lint: PEP8 E265: block comment should start with '# ' | |||||
#import os | #import os | ||||
Lint: PEP8 E265 block comment should start with '# ' Lint: PEP8 E265: block comment should start with '# ' | |||||
#stat = os.stat(filepath) | #stat = os.stat(filepath) | ||||
Lint: PEP8 E265 block comment should start with '# ' Lint: PEP8 E265: block comment should start with '# ' | |||||
#fileage = datetime.datetime.fromtimestamp(stat.st_mtime) | #fileage = datetime.datetime.fromtimestamp(stat.st_mtime) | ||||
Lint: PEP8 E265 block comment should start with '# ' Lint: PEP8 E265: block comment should start with '# ' | |||||
#now = datetime.datetime.now() | #now = datetime.datetime.now() | ||||
Lint: PEP8 E265 block comment should start with '# ' Lint: PEP8 E265: block comment should start with '# ' | |||||
#delta = now - fileage | #delta = now - fileage | ||||
Lint: PEP8 E265 block comment should start with '# ' Lint: PEP8 E265: block comment should start with '# ' | |||||
#print "file:", filepath, "fileage:", fileage, "now:", now, "delta(seconds):", delta.seconds | #print "file:", filepath, "fileage:", fileage, "now:", now, "delta(seconds):", delta.seconds | ||||
Lint: PEP8 E265 block comment should start with '# ' Lint: PEP8 E265: block comment should start with '# ' | |||||
Lint: PEP8 E501 line too long (96 > 79 characters) Lint: PEP8 E501: line too long (96 > 79 characters) | |||||
#if delta.seconds > 1800: | #if delta.seconds > 1800: | ||||
Lint: PEP8 E265 block comment should start with '# ' Lint: PEP8 E265: block comment should start with '# ' | |||||
## TODO: Send NDR back to user | ## TODO: Send NDR back to user | ||||
Lint: PEP8 E266 too many leading '#' for block comment Lint: PEP8 E266: too many leading '#' for block comment | |||||
#log.debug(_("Message in file %s older then 1800 seconds, deleting") % (filepath), level=8) | #log.debug(_("Message in file %s older then 1800 seconds, deleting") % (filepath), level=8) | ||||
Lint: PEP8 E265 block comment should start with '# ' Lint: PEP8 E265: block comment should start with '# ' | |||||
Lint: PEP8 E501 line too long (99 > 79 characters) Lint: PEP8 E501: line too long (99 > 79 characters) | |||||
#os.unlink(filepath) | #os.unlink(filepath) | ||||
Lint: PEP8 E265 block comment should start with '# ' Lint: PEP8 E265: block comment should start with '# ' | |||||
def cb_action_REJECT(module, filepath): | def cb_action_REJECT(module, filepath): | ||||
Lint: PEP8 E302 expected 2 blank lines, found 1 Lint: PEP8 E302: expected 2 blank lines, found 1 | |||||
log.info(_("Rejecting message in %s (by module %s)") % (filepath, module)) | log.info(_("Rejecting message in %s (by module %s)") % (filepath, module)) | ||||
# parse message headers | # parse message headers | ||||
message = Parser().parse(open(filepath, 'r'), True) | message = Parser().parse(open(filepath, 'r'), True) | ||||
envelope_sender = getaddresses(message.get_all('From', [])) | envelope_sender = getaddresses(message.get_all('From', [])) | ||||
recipients = getaddresses(message.get_all('To', [])) + \ | recipients = getaddresses(message.get_all('To', [])) + \ | ||||
getaddresses(message.get_all('Cc', [])) + \ | getaddresses(message.get_all('Cc', [])) + \ | ||||
Lint: PEP8 E127 continuation line over-indented for visual indent Lint: PEP8 E127: continuation line over-indented for visual indent | |||||
getaddresses(message.get_all('X-Kolab-To', [])) | getaddresses(message.get_all('X-Kolab-To', [])) | ||||
Lint: PEP8 E127 continuation line over-indented for visual indent Lint: PEP8 E127: continuation line over-indented for visual indent | |||||
_recipients = [] | _recipients = [] | ||||
for recipient in recipients: | for recipient in recipients: | ||||
if not recipient[0] == '': | if not recipient[0] == '': | ||||
_recipients.append('%s <%s>' % (recipient[0], recipient[1])) | _recipients.append('%s <%s>' % (recipient[0], recipient[1])) | ||||
else: | else: | ||||
_recipients.append('%s' % (recipient[1])) | _recipients.append('%s' % (recipient[1])) | ||||
▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | result = _sendmail( | ||||
"MAILER-DAEMON@%s" % (constants.fqdn), | "MAILER-DAEMON@%s" % (constants.fqdn), | ||||
[formataddr(envelope_sender[0])], | [formataddr(envelope_sender[0])], | ||||
msg.as_string() | msg.as_string() | ||||
) | ) | ||||
if result: | if result: | ||||
os.unlink(filepath) | os.unlink(filepath) | ||||
def cb_action_ACCEPT(module, filepath): | def cb_action_ACCEPT(module, filepath): | ||||
Lint: PEP8 E302 expected 2 blank lines, found 1 Lint: PEP8 E302: expected 2 blank lines, found 1 | |||||
log.info(_("Accepting message in %s (by module %s)") % (filepath, module)) | log.info(_("Accepting message in %s (by module %s)") % (filepath, module)) | ||||
log.debug(_("Accepting message in: %r") %(filepath), level=8) | log.debug(_("Accepting message in: %r") %(filepath), level=8) | ||||
Lint: PEP8 E225 missing whitespace around operator Lint: PEP8 E225: missing whitespace around operator | |||||
# parse message headers | # parse message headers | ||||
message = Parser().parse(open(filepath, 'r'), True) | message = Parser().parse(open(filepath, 'r'), True) | ||||
sender = [formataddr(x) for x in getaddresses(message.get_all('X-Kolab-From', []))] | sender = [formataddr(x) for x in getaddresses(message.get_all('X-Kolab-From', []))] | ||||
Lint: PEP8 E501 line too long (87 > 79 characters) Lint: PEP8 E501: line too long (87 > 79 characters) | |||||
recipients = [formataddr(x) for x in getaddresses(message.get_all('X-Kolab-To', []))] | recipients = [formataddr(x) for x in getaddresses(message.get_all('X-Kolab-To', []))] | ||||
Lint: PEP8 E501 line too long (89 > 79 characters) Lint: PEP8 E501: line too long (89 > 79 characters) | |||||
log.debug(_("recipients: %r") % (recipients)) | log.debug(_("recipients: %r") % (recipients)) | ||||
# delete X-Kolab-* headers | # delete X-Kolab-* headers | ||||
del message['X-Kolab-From'] | del message['X-Kolab-From'] | ||||
del message['X-Kolab-To'] | del message['X-Kolab-To'] | ||||
result = _sendmail( | result = _sendmail( | ||||
sender, | sender, | ||||
recipients, | recipients, | ||||
# - Make sure we do not send this as binary. | # - Make sure we do not send this as binary. | ||||
# - Second, strip NUL characters - I don't know where they | # - Second, strip NUL characters - I don't know where they | ||||
# come from (TODO) | # come from (TODO) | ||||
# - Third, a character return is inserted somewhere. It | # - Third, a character return is inserted somewhere. It | ||||
# divides the body from the headers - and we don't like (TODO) | # divides the body from the headers - and we don't like (TODO) | ||||
# @TODO: check if we need Parser().parse() to load the whole message | # @TODO: check if we need Parser().parse() to load the whole message | ||||
Lint: PEP8 E501 line too long (80 > 79 characters) Lint: PEP8 E501: line too long (80 > 79 characters) | |||||
message.as_string() | message.as_string() | ||||
) | ) | ||||
if result: | if result: | ||||
os.unlink(filepath) | os.unlink(filepath) | ||||
def register_group(dirname, module): | def register_group(dirname, module): | ||||
Lint: PEP8 E302 expected 2 blank lines, found 1 Lint: PEP8 E302: expected 2 blank lines, found 1 | |||||
modules_base_path = os.path.join(os.path.dirname(__file__), module) | modules_base_path = os.path.join(os.path.dirname(__file__), module) | ||||
modules[module] = {} | modules[module] = {} | ||||
for modules_path, dirnames, filenames in os.walk(modules_base_path): | for modules_path, dirnames, filenames in os.walk(modules_base_path): | ||||
if not modules_path == modules_base_path: | if not modules_path == modules_base_path: | ||||
continue | continue | ||||
for filename in filenames: | for filename in filenames: | ||||
if filename.startswith('module_') and filename.endswith('.py'): | if filename.startswith('module_') and filename.endswith('.py'): | ||||
module_name = filename.replace('.py','') | module_name = filename.replace('.py','') | ||||
Lint: PEP8 E231 missing whitespace after ',' Lint: PEP8 E231: missing whitespace after ',' | |||||
name = module_name.replace('module_', '') | name = module_name.replace('module_', '') | ||||
# TODO: Error recovery from incomplete / incorrect modules. | # TODO: Error recovery from incomplete / incorrect modules. | ||||
exec( | exec( | ||||
"from %s.%s import __init__ as %s_%s_register" % ( | "from %s.%s import __init__ as %s_%s_register" % ( | ||||
module, | module, | ||||
module_name, | module_name, | ||||
module, | module, | ||||
name | name | ||||
) | ) | ||||
) | ) | ||||
exec("%s_%s_register()" % (module,name)) | exec("%s_%s_register()" % (module,name)) | ||||
Lint: PEP8 E231 missing whitespace after ',' Lint: PEP8 E231: missing whitespace after ',' | |||||
def register(name, func, group=None, description=None, aliases=[], heartbeat=None): | def register(name, func, group=None, description=None, aliases=[], heartbeat=None): | ||||
Lint: PEP8 E302 expected 2 blank lines, found 1 Lint: PEP8 E302: expected 2 blank lines, found 1 | |||||
Lint: PEP8 E501 line too long (83 > 79 characters) Lint: PEP8 E501: line too long (83 > 79 characters) | |||||
if not group == None: | if not group == None: | ||||
Lint: PEP8 E711 comparison to None should be 'if cond is None:' Lint: PEP8 E711: comparison to None should be 'if cond is None:' | |||||
module = "%s_%s" % (group,name) | module = "%s_%s" % (group,name) | ||||
Lint: PEP8 E231 missing whitespace after ',' Lint: PEP8 E231: missing whitespace after ',' | |||||
else: | else: | ||||
module = name | module = name | ||||
if isinstance(aliases, basestring): | if isinstance(aliases, basestring): | ||||
aliases = [aliases] | aliases = [aliases] | ||||
if modules.has_key(module): | if modules.has_key(module): | ||||
log.fatal(_("Module '%s' already registered") % (module)) | log.fatal(_("Module '%s' already registered") % (module)) | ||||
sys.exit(1) | sys.exit(1) | ||||
if callable(func): | if callable(func): | ||||
if group == None: | if group == None: | ||||
Lint: PEP8 E711 comparison to None should be 'if cond is None:' Lint: PEP8 E711: comparison to None should be 'if cond is None:' | |||||
modules[name] = { | modules[name] = { | ||||
'function': func, | 'function': func, | ||||
'description': description | 'description': description | ||||
} | } | ||||
else: | else: | ||||
modules[group][name] = { | modules[group][name] = { | ||||
'function': func, | 'function': func, | ||||
'description': description | 'description': description | ||||
Show All 14 Lines |
expected 2 blank lines, found 1