mirror of
https://github.com/jlu5/PyLink.git
synced 2024-11-30 14:49:28 +01:00
998beb51b5
It is possible for PyLink to shutdown indirectly by disconnecting all networks. In these cases, the shutdown routines never ran at all...
95 lines
3.9 KiB
Python
Executable File
95 lines
3.9 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
PyLink IRC Services launcher.
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
try:
|
|
from pylinkirc import world
|
|
except ImportError:
|
|
sys.stderr.write("ERROR: Failed to import PyLink main module (pylinkirc.world).\n\nIf you are "
|
|
"running PyLink from source, please install PyLink first using 'python3 "
|
|
"setup.py install' (global install) or 'python3 setup.py install --user'"
|
|
" (local install)\n")
|
|
sys.exit(1)
|
|
from pylinkirc import conf, __version__, real_version
|
|
|
|
if __name__ == '__main__':
|
|
import argparse
|
|
|
|
parser = argparse.ArgumentParser(description='Starts an instance of PyLink IRC Services.')
|
|
parser.add_argument('config', help='specifies the path to the config file (defaults to pylink.yml)', nargs='?', default='pylink.yml')
|
|
parser.add_argument("-v", "--version", help="displays the program version and exits", action='store_true')
|
|
parser.add_argument("-c", "--check-pid", help="enables PID file checking", action='store_true')
|
|
parser.add_argument("-n", "--no-pid", help="skips generating PID files", action='store_true')
|
|
args = parser.parse_args()
|
|
|
|
if args.version: # Display version and exit
|
|
print('PyLink %s (in VCS: %s)' % (__version__, real_version))
|
|
sys.exit()
|
|
|
|
# FIXME: we can't pass logging on to conf until we set up the config...
|
|
conf.loadConf(args.config)
|
|
|
|
from pylinkirc.log import log
|
|
from pylinkirc import classes, utils, coremods
|
|
log.info('PyLink %s starting...', __version__)
|
|
|
|
# Set terminal window title. See https://bbs.archlinux.org/viewtopic.php?id=85567
|
|
# and https://stackoverflow.com/questions/7387276/
|
|
if os.name == 'nt':
|
|
import ctypes
|
|
ctypes.windll.kernel32.SetConsoleTitleW("PyLink %s" % __version__)
|
|
elif os.name == 'posix':
|
|
sys.stdout.write("\x1b]2;PyLink %s\x07" % __version__)
|
|
|
|
# Check for a pid file. This stops instance overlap and user mistakes, which are especially an
|
|
# issue for clientbot...
|
|
if args.check_pid:
|
|
config = conf.confname
|
|
if os.path.exists("%s.pid" % config):
|
|
log.error("PID file exists; aborting! If PyLink didn't shut down cleanly last time it "
|
|
"was run, or you're upgrading from PyLink < 1.1-dev, delete %s.pid and try "
|
|
"again." % config)
|
|
sys.exit(1)
|
|
|
|
# Write a PID file unless specifically told not to.
|
|
if not args.no_pid:
|
|
with open('%s.pid' % conf.confname, 'w') as f:
|
|
f.write(str(os.getpid()))
|
|
|
|
# Import plugins first globally, because they can listen for events
|
|
# that happen before the connection phase.
|
|
to_load = conf.conf['plugins']
|
|
utils.resetModuleDirs()
|
|
# Here, we override the module lookup and import the plugins
|
|
# dynamically depending on which were configured.
|
|
for plugin in to_load:
|
|
try:
|
|
world.plugins[plugin] = pl = utils.loadPlugin(plugin)
|
|
except Exception as e:
|
|
log.exception('Failed to load plugin %r: %s: %s', plugin, type(e).__name__, str(e))
|
|
else:
|
|
if hasattr(pl, 'main'):
|
|
log.debug('Calling main() function of plugin %r', pl)
|
|
pl.main()
|
|
|
|
# Initialize all the networks one by one
|
|
for network, sdata in conf.conf['servers'].items():
|
|
|
|
try:
|
|
protoname = sdata['protocol']
|
|
except (KeyError, TypeError):
|
|
log.error("(%s) Configuration error: No protocol module specified, aborting.", network)
|
|
else:
|
|
# Fetch the correct protocol module
|
|
proto = utils.getProtocolModule(protoname)
|
|
world.networkobjects[network] = irc = classes.Irc(network, proto, conf.conf)
|
|
|
|
world.started.set()
|
|
log.info("Loaded plugins: %s", ', '.join(sorted(world.plugins.keys())))
|
|
|
|
from pylinkirc import coremods
|
|
coremods.permissions.resetPermissions() # XXX we should probably move this to run on import
|