mirror of
https://github.com/jlu5/PyLink.git
synced 2024-11-01 01:09:22 +01:00
b3387f2d41
This allows conf methods to access to global logger by via an optional 'logger' argument. However, the caveat is that the logging facilities are still unavailable on first start, because log can only be imported *after* the configuration is loaded.
99 lines
4.0 KiB
Python
99 lines
4.0 KiB
Python
"""
|
|
conf.py - PyLink configuration core.
|
|
|
|
This module is used to access the configuration of the current PyLink instance.
|
|
It provides simple checks for validating and loading YAML-format configurations from arbitrary files.
|
|
"""
|
|
|
|
try:
|
|
import yaml
|
|
except ImportError:
|
|
raise ImportError("Please install PyYAML and try again.")
|
|
|
|
import sys
|
|
import os.path
|
|
from collections import defaultdict
|
|
|
|
from . import world
|
|
|
|
conf = {'bot':
|
|
{
|
|
'nick': 'PyLink',
|
|
'user': 'pylink',
|
|
'realname': 'PyLink Service Client',
|
|
'serverdesc': 'Unconfigured PyLink'
|
|
},
|
|
'logging':
|
|
{
|
|
'stdout': 'INFO'
|
|
},
|
|
'servers':
|
|
# Wildcard defaultdict! This means that
|
|
# any network name you try will work and return
|
|
# this basic template:
|
|
defaultdict(lambda: {'ip': '0.0.0.0',
|
|
'port': 7000,
|
|
'recvpass': "unconfigured",
|
|
'sendpass': "unconfigured",
|
|
'protocol': "null",
|
|
'hostname': "pylink.unconfigured",
|
|
'sid': "000",
|
|
'maxnicklen': 20,
|
|
'sidrange': '0##'
|
|
})
|
|
}
|
|
confname = 'unconfigured'
|
|
|
|
def validateConf(conf, logger=None):
|
|
"""Validates a parsed configuration dict."""
|
|
assert type(conf) == dict, "Invalid configuration given: should be type dict, not %s." % type(conf).__name__
|
|
|
|
for section in ('bot', 'servers', 'login', 'logging'):
|
|
assert conf.get(section), "Missing %r section in config." % section
|
|
|
|
# Make sure at least one form of authentication is valid.
|
|
# Also we'll warn them that login:user/login:password is deprecated
|
|
if conf['login'].get('password') or conf['login'].get('user'):
|
|
e = "The 'login:user' and 'login:password' options are deprecated since PyLink 1.1. " \
|
|
"Please switch to the new 'login:accounts' format as outlined in the example config."
|
|
if logger:
|
|
logger.warning(e)
|
|
else:
|
|
# FIXME: we need a better fallback when log isn't available on first
|
|
# start.
|
|
print('WARNING: %s' % e)
|
|
|
|
old_login_valid = type(conf['login'].get('password')) == type(conf['login'].get('user')) == str
|
|
newlogins = conf['login'].get('accounts', {})
|
|
new_login_valid = len(newlogins) >= 1
|
|
assert old_login_valid or new_login_valid, "No accounts were set, aborting!"
|
|
for account, block in newlogins.items():
|
|
assert type(account) == str, "Bad username format %s" % account
|
|
assert type(block.get('password')) == str, "Bad password %s for account %s" % (block.get('password'), account)
|
|
|
|
assert conf['login'].get('password') != "changeme", "You have not set the login details correctly!"
|
|
|
|
return conf
|
|
|
|
|
|
def loadConf(filename, errors_fatal=True, logger=None):
|
|
"""Loads a PyLink configuration file from the filename given."""
|
|
global confname, conf, fname
|
|
# Note: store globally the last loaded conf filename, for REHASH in coremods/control.
|
|
fname = filename
|
|
# For the internal config name, strip off any .yml extensions and absolute paths
|
|
confname = os.path.basename(filename).split('.', 1)[0]
|
|
try:
|
|
with open(filename, 'r') as f:
|
|
conf = yaml.load(f)
|
|
conf = validateConf(conf, logger=logger)
|
|
except Exception as e:
|
|
print('ERROR: Failed to load config from %r: %s: %s' % (filename, type(e).__name__, e), file=sys.stderr)
|
|
print(' Users upgrading from users < 0.9-alpha1 should note that the default configuration has been renamed to *pylink.yml*, not *config.yml*', file=sys.stderr)
|
|
|
|
if errors_fatal:
|
|
sys.exit(4)
|
|
raise
|
|
else:
|
|
return conf
|