Add web app support to standalone mode
This commit is contained in:
parent
fc516d78b7
commit
8b1685a9ea
4 changed files with 51 additions and 7 deletions
|
@ -54,7 +54,7 @@ class MaubotServer:
|
||||||
|
|
||||||
self.runner = web.AppRunner(self.app, access_log_class=AccessLogger)
|
self.runner = web.AppRunner(self.app, access_log_class=AccessLogger)
|
||||||
|
|
||||||
async def handle_plugin_path(self, request: web.Request) -> web.Response:
|
async def handle_plugin_path(self, request: web.Request) -> web.StreamResponse:
|
||||||
for path, app in self.plugin_routes.items():
|
for path, app in self.plugin_routes.items():
|
||||||
if request.path.startswith(path):
|
if request.path.startswith(path):
|
||||||
request = request.clone(rel_url=request.rel_url
|
request = request.clone(rel_url=request.rel_url
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
# 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/>.
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
from typing import Optional, Type, cast
|
from typing import Optional, Type, cast
|
||||||
from aiohttp import ClientSession
|
|
||||||
import logging.config
|
import logging.config
|
||||||
import importlib
|
import importlib
|
||||||
import argparse
|
import argparse
|
||||||
|
@ -27,6 +26,8 @@ import sys
|
||||||
from ruamel.yaml import YAML
|
from ruamel.yaml import YAML
|
||||||
from ruamel.yaml.comments import CommentedMap
|
from ruamel.yaml.comments import CommentedMap
|
||||||
import sqlalchemy as sql
|
import sqlalchemy as sql
|
||||||
|
from aiohttp import web, hdrs, ClientSession
|
||||||
|
from yarl import URL
|
||||||
|
|
||||||
from mautrix.util.config import RecursiveDict, BaseMissingError
|
from mautrix.util.config import RecursiveDict, BaseMissingError
|
||||||
from mautrix.util.db import Base
|
from mautrix.util.db import Base
|
||||||
|
@ -35,7 +36,9 @@ from mautrix.types import (Filter, RoomFilter, RoomEventFilter, StrippedStateEve
|
||||||
EventType, Membership, FilterID, SyncToken)
|
EventType, Membership, FilterID, SyncToken)
|
||||||
|
|
||||||
from ..plugin_base import Plugin
|
from ..plugin_base import Plugin
|
||||||
|
from ..plugin_server import PluginWebApp
|
||||||
from ..loader import PluginMeta
|
from ..loader import PluginMeta
|
||||||
|
from ..server import AccessLogger
|
||||||
from ..matrix import MaubotMatrixClient
|
from ..matrix import MaubotMatrixClient
|
||||||
from ..lib.store_proxy import SyncStoreProxy
|
from ..lib.store_proxy import SyncStoreProxy
|
||||||
from ..__meta__ import __version__
|
from ..__meta__ import __version__
|
||||||
|
@ -145,6 +148,25 @@ if meta.config:
|
||||||
log.fatal("Failed to load plugin config", exc_info=True)
|
log.fatal("Failed to load plugin config", exc_info=True)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
if meta.webapp:
|
||||||
|
plugin_webapp = PluginWebApp()
|
||||||
|
web_app = web.Application(router=plugin_webapp)
|
||||||
|
web_runner = web.AppRunner(web_app, access_log_class=AccessLogger)
|
||||||
|
web_base_path = config["server.base_path"].rstrip("/")
|
||||||
|
public_url = str(URL(config["server.public_url"]) / web_base_path).rstrip("/")
|
||||||
|
|
||||||
|
# async def _handle_plugin_request(req: web.Request) -> web.StreamResponse:
|
||||||
|
# assert req.path.startswith(web_base_path)
|
||||||
|
# req = req.clone(rel_url=req.rel_url
|
||||||
|
# .with_path(req.rel_url.path[len(web_base_path)])
|
||||||
|
# .with_query(req.query_string))
|
||||||
|
# return await plugin_webapp.handle(req)
|
||||||
|
#
|
||||||
|
# web_app.router = plugin_webapp
|
||||||
|
# web_app.router.add_route(hdrs.METH_ANY, web_base_path, _handle_plugin_request)
|
||||||
|
else:
|
||||||
|
web_app = web_runner = public_url = plugin_webapp = None
|
||||||
|
|
||||||
loop = asyncio.get_event_loop()
|
loop = asyncio.get_event_loop()
|
||||||
|
|
||||||
client: Optional[MaubotMatrixClient] = None
|
client: Optional[MaubotMatrixClient] = None
|
||||||
|
@ -220,16 +242,25 @@ async def main():
|
||||||
plugin_log = cast(TraceLogger, logging.getLogger("maubot.instance.__main__"))
|
plugin_log = cast(TraceLogger, logging.getLogger("maubot.instance.__main__"))
|
||||||
bot = plugin(client=client, loop=loop, http=http_client, instance_id="__main__",
|
bot = plugin(client=client, loop=loop, http=http_client, instance_id="__main__",
|
||||||
log=plugin_log, config=bot_config, database=db if meta.database else None,
|
log=plugin_log, config=bot_config, database=db if meta.database else None,
|
||||||
webapp=None, webapp_url=None, loader=loader)
|
webapp=plugin_webapp, webapp_url=public_url, loader=loader)
|
||||||
|
|
||||||
await bot.internal_start()
|
await bot.internal_start()
|
||||||
|
|
||||||
|
if web_runner:
|
||||||
|
await web_runner.setup()
|
||||||
|
site = web.TCPSite(web_runner, config["server.hostname"], config["server.port"])
|
||||||
|
await site.start()
|
||||||
|
log.info(f"Web server listening on {site.name}")
|
||||||
|
|
||||||
|
|
||||||
async def stop() -> None:
|
async def stop() -> None:
|
||||||
client.stop()
|
client.stop()
|
||||||
await bot.internal_stop()
|
await bot.internal_stop()
|
||||||
if crypto_db:
|
if crypto_db:
|
||||||
await crypto_db.stop()
|
await crypto_db.stop()
|
||||||
|
if web_runner:
|
||||||
|
await web_runner.shutdown()
|
||||||
|
await web_runner.cleanup()
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -36,12 +36,13 @@ class Config(BaseFileConfig):
|
||||||
copy("user.autojoin")
|
copy("user.autojoin")
|
||||||
copy("user.displayname")
|
copy("user.displayname")
|
||||||
copy("user.avatar_url")
|
copy("user.avatar_url")
|
||||||
|
if "server" in base:
|
||||||
|
copy("server.hostname")
|
||||||
|
copy("server.port")
|
||||||
|
copy("server.base_path")
|
||||||
|
copy("server.public_url")
|
||||||
if "database" in base:
|
if "database" in base:
|
||||||
copy("database")
|
copy("database")
|
||||||
if "plugin_config" in base:
|
if "plugin_config" in base:
|
||||||
copy("plugin_config")
|
copy("plugin_config")
|
||||||
if "server" in base:
|
|
||||||
copy("server.hostname")
|
|
||||||
copy("server.port")
|
|
||||||
copy("server.public_url")
|
|
||||||
copy("logging")
|
copy("logging")
|
||||||
|
|
|
@ -21,6 +21,18 @@ user:
|
||||||
# if you want the bot to handle messages that were sent while the bot was down.
|
# if you want the bot to handle messages that were sent while the bot was down.
|
||||||
ignore_first_sync: true
|
ignore_first_sync: true
|
||||||
|
|
||||||
|
# Web server settings. These will only take effect if the plugin requests it using `webapp: true` in the meta file.
|
||||||
|
server:
|
||||||
|
# The IP and port to listen to.
|
||||||
|
hostname: 0.0.0.0
|
||||||
|
port: 8080
|
||||||
|
# The base path where the plugin's web resources will be served. Unlike the normal mode,
|
||||||
|
# the webserver is dedicated for a single bot in standalone mode, so the default path
|
||||||
|
# is just /. If you want to emulate normal mode, set this to /_matrix/maubot/plugin/something
|
||||||
|
base_path: /
|
||||||
|
# The public URL where the resources are available. The base path is automatically appended to this.
|
||||||
|
public_url: https://example.com
|
||||||
|
|
||||||
# The database for the plugin. Used for plugin data, the sync token and e2ee data (if enabled).
|
# The database for the plugin. Used for plugin data, the sync token and e2ee data (if enabled).
|
||||||
# SQLite and Postgres are supported.
|
# SQLite and Postgres are supported.
|
||||||
database: sqlite:///bot.db
|
database: sqlite:///bot.db
|
||||||
|
|
Loading…
Reference in a new issue