maubot/maubot/__main__.py

108 lines
3.9 KiB
Python
Raw Normal View History

2018-09-26 07:32:24 +00:00
# maubot - A plugin-based Matrix bot system.
2019-06-08 14:42:07 +00:00
# Copyright (C) 2019 Tulir Asokan
2018-09-26 07:32:24 +00:00
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import logging.config
import argparse
2018-10-16 13:41:02 +00:00
import asyncio
import signal
2018-09-26 07:32:24 +00:00
import copy
2018-10-16 13:41:02 +00:00
import sys
2018-09-26 07:32:24 +00:00
from .config import Config
from .db import init as init_db
2018-10-16 13:41:02 +00:00
from .server import MaubotServer
from .client import Client, init as init_client_class
from .loader.zip import init as init_zip_loader
from .instance import init as init_plugin_instance_class
from .management.api import init as init_mgmt_api
2018-10-14 19:08:11 +00:00
from .__meta__ import __version__
2018-09-26 07:32:24 +00:00
parser = argparse.ArgumentParser(description="A plugin-based Matrix bot system.",
prog="python -m maubot")
parser.add_argument("-c", "--config", type=str, default="config.yaml",
metavar="<path>", help="the path to your config file")
2018-10-16 19:15:35 +00:00
parser.add_argument("-b", "--base-config", type=str, default="example-config.yaml",
metavar="<path>", help="the path to the example config "
"(for automatic config updates)")
2018-09-26 07:32:24 +00:00
args = parser.parse_args()
config = Config(args.config, args.base_config)
config.load()
config.update()
logging.config.dictConfig(copy.deepcopy(config["logging"]))
stop_log_listener = None
if config["api_features.log"]:
from .management.api.log import init as init_log_listener, stop_all as stop_log_listener
init_log_listener()
2018-10-16 19:15:35 +00:00
log = logging.getLogger("maubot.init")
log.info(f"Initializing maubot {__version__}")
2018-10-16 13:41:02 +00:00
loop = asyncio.get_event_loop()
init_zip_loader(config)
db_session = init_db(config)
clients = init_client_class(db_session, loop)
management_api = init_mgmt_api(config, loop)
2019-03-07 19:35:35 +00:00
server = MaubotServer(management_api, config, loop)
2019-03-06 20:27:23 +00:00
plugins = init_plugin_instance_class(db_session, config, server, loop)
2018-10-16 22:30:08 +00:00
for plugin in plugins:
plugin.load()
2018-10-16 19:15:35 +00:00
2018-10-20 18:01:13 +00:00
signal.signal(signal.SIGINT, signal.default_int_handler)
signal.signal(signal.SIGTERM, signal.default_int_handler)
2018-10-21 23:01:06 +00:00
async def periodic_commit():
while True:
2018-10-21 23:01:06 +00:00
await asyncio.sleep(60)
db_session.commit()
periodic_commit_task: asyncio.Future = None
2018-10-16 13:41:02 +00:00
try:
log.info("Starting server")
loop.run_until_complete(server.start())
log.info("Starting clients and plugins")
2018-11-01 21:31:30 +00:00
loop.run_until_complete(asyncio.gather(*[client.start() for client in clients], loop=loop))
log.info("Startup actions complete, running forever")
periodic_commit_task = asyncio.ensure_future(periodic_commit(), loop=loop)
2018-10-16 13:41:02 +00:00
loop.run_forever()
except KeyboardInterrupt:
2018-11-01 21:31:30 +00:00
log.info("Interrupt received, stopping HTTP clients/servers and saving database")
if periodic_commit_task is not None:
periodic_commit_task.cancel()
2018-11-01 21:31:30 +00:00
log.debug("Stopping clients")
loop.run_until_complete(asyncio.gather(*[client.stop() for client in Client.cache.values()],
loop=loop))
2018-10-16 22:30:08 +00:00
db_session.commit()
if stop_log_listener is not None:
log.debug("Closing websockets")
loop.run_until_complete(stop_log_listener())
2018-11-01 21:31:30 +00:00
log.debug("Stopping server")
try:
loop.run_until_complete(asyncio.wait_for(server.stop(), 5, loop=loop))
except asyncio.TimeoutError:
log.warning("Stopping server timed out")
2018-11-01 21:31:30 +00:00
log.debug("Closing event loop")
loop.close()
2018-10-20 18:01:13 +00:00
log.debug("Everything stopped, shutting down")
2018-10-16 13:41:02 +00:00
sys.exit(0)