refactor endpoints to use new plugin system

This commit is contained in:
Robert Resch 2022-03-06 18:57:17 +01:00
parent 329217ba8f
commit be21b8bc72
15 changed files with 127 additions and 215 deletions

View file

@ -1,8 +1,6 @@
import asyncio
import importlib
import logging
import os
import pkgutil
import socket
import sys
@ -56,16 +54,6 @@ mqtt_helperbot: MQTTHelperBot
conf_server: ConfServer
xmpp_server: XMPPServer
# Plugins
sys.path.append(os.path.join(bumper_dir, "bumper", "plugins"))
sys.path.append(os.path.join(data_dir, "plugins"))
discovered_plugins = {
name: importlib.import_module(name)
for finder, name, ispkg in pkgutil.iter_modules()
if name.startswith("bumper_")
}
shutting_down = False
bumperlog = get_logger("bumper")

View file

@ -24,7 +24,6 @@ from aiohttp.web_response import Response, StreamResponse
import bumper
from .db import bot_get, bot_remove, client_get, client_remove, db_get
from .plugins import ConfServerApp, WebserverPlugin, WebserverSubApi
from .util import get_logger
from .web.plugins import add_plugins
@ -104,50 +103,8 @@ class ConfServer:
]
)
# common api paths
api_v1 = {"prefix": "/v1/", "app": web.Application()} # for /v1/
apis = {
WebserverSubApi.V1: api_v1,
}
add_plugins(self._app)
# Load plugins
for module in bumper.discovered_plugins.values():
plugins = [
m[1]
for m in inspect.getmembers(module, inspect.isclass)
if m[1].__module__ == module.__name__
]
for plugin_class in plugins:
if issubclass(plugin_class, WebserverPlugin):
plugin = plugin_class()
logging.debug(
f"Adding confserver sub_api ({plugin.__class__.__name__})"
)
apis[plugin.sub_api]["app"].add_routes(plugin.routes)
elif issubclass(plugin_class, ConfServerApp):
plugin = plugin_class()
if plugin.plugin_type == "sub_api": # app or sub_api
convert_api = {
"api_v1": WebserverSubApi.V1,
"api_v2": WebserverSubApi.V2,
"portal_api": WebserverSubApi.API,
"upload_api": WebserverSubApi.UPLOAD,
}
api = convert_api.get(plugin.sub_api, None)
if api and plugin.routes:
logging.debug(f"Adding confserver sub_api ({plugin.name})")
apis[api]["app"].add_routes(plugin.routes)
elif plugin.plugin_type == "app":
if plugin.path_prefix and plugin.app:
logging.debug(f"Adding confserver plugin ({plugin.name})")
self._app.add_subapp(plugin.path_prefix, plugin.app)
for api in apis:
self._app.add_subapp(apis[api]["prefix"], apis[api]["app"])
async def start(self) -> None:
"""Start server."""
try:

View file

@ -1,39 +0,0 @@
from abc import abstractmethod
from enum import Enum
from typing import Iterable
from aiohttp.web_routedef import AbstractRouteDef
class ConfServerApp:
name = None
plugin_type = None
path_prefix = None
app = None
sub_api = None
routes = None
class WebserverSubApi(str, Enum):
"""Enum with all different sub apis."""
V1 = "v1"
V2 = "v2"
API = "api"
UPLOAD = "upload"
class WebserverPlugin:
"""Abstract webserver plugin."""
@property
@abstractmethod
def sub_api(self) -> WebserverSubApi:
"""Sub api."""
raise NotImplementedError
@property
@abstractmethod
def routes(self) -> Iterable[AbstractRouteDef]:
"""Plugin routes."""
raise NotImplementedError

View file

@ -1,20 +0,0 @@
from aiohttp import web
from bumper import plugins
from bumper.web import auth_util
class v1_global_auth(plugins.ConfServerApp):
def __init__(self):
self.name = "v1_global_auth"
self.plugin_type = "sub_api"
self.sub_api = "api_v1"
self.routes = [
web.route(
"*",
"/global/auth/getAuthCode",
auth_util.get_authcode,
name="v1_global_auth_getAuthCode",
),
]

View file

@ -18,7 +18,7 @@ from bumper.models import ERR_COMMON
from .. import WebserverPlugin
async def _handle_lg_log(request: Request)->Response:
async def _handle_lg_log(request: Request) -> Response:
# EcoVacs Home
randomid = "".join(random.sample(string.ascii_letters, 6))

View file

@ -0,0 +1 @@
"""V1 plugins module."""

View file

@ -0,0 +1,23 @@
"""Global auth plugin module."""
from typing import Iterable
from aiohttp import web
from aiohttp.web_routedef import AbstractRouteDef
from ... import auth_util
from .. import WebserverPlugin
class GlobalAuthPlugin(WebserverPlugin):
"""Global auth plugin."""
@property
def routes(self) -> Iterable[AbstractRouteDef]:
"""Plugin routes."""
return [
web.route(
"*",
"/global/auth/getAuthCode",
auth_util.get_authcode,
),
]

View file

@ -0,0 +1 @@
"""Private plugins module."""

View file

@ -1,30 +1,32 @@
"""Ad plugin module."""
import logging
from typing import Iterable
from aiohttp import web
from aiohttp.web_routedef import AbstractRouteDef
from bumper import plugins
from bumper.models import RETURN_API_SUCCESS
from bumper.util import get_current_time_as_millis
from ... import WebserverPlugin
class v1_private_ad(plugins.ConfServerApp):
def __init__(self):
self.name = "v1_private_ad"
self.plugin_type = "sub_api"
self.sub_api = "api_v1"
self.routes = [
class AdPlugin(WebserverPlugin):
"""Ad plugin."""
@property
def routes(self) -> Iterable[AbstractRouteDef]:
"""Plugin routes."""
return [
web.route(
"*",
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/ad/getAdByPositionType",
"/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/ad/getAdByPositionType",
self.handle_getAdByPositionType,
name="v1_ad_getAdByPositionType",
),
web.route(
"*",
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/ad/getBootScreen",
"/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/ad/getBootScreen",
self.handle_getBootScreen,
name="v1_ad_getBootScreen",
),
]

View file

@ -1,23 +1,27 @@
"""Campaign plugin module."""
import logging
from datetime import datetime, timedelta
from typing import Iterable
from aiohttp import web
from aiohttp.web_routedef import AbstractRouteDef
from bumper import plugins
from bumper.models import RETURN_API_SUCCESS
from bumper.util import convert_to_millis, get_current_time_as_millis
from ... import WebserverPlugin
class v1_private_campaign(plugins.ConfServerApp):
def __init__(self):
self.name = "v1_private_campaign"
self.plugin_type = "sub_api"
self.sub_api = "api_v1"
self.routes = [
class CampaignPlugin(WebserverPlugin):
"""Campaign plugin."""
@property
def routes(self) -> Iterable[AbstractRouteDef]:
"""Plugin routes."""
return [
web.route(
"*",
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/campaign/homePageAlert",
"/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/campaign/homePageAlert",
self.handle_homePageAlert,
name="v1_campaign_homePageAlert",
),

View file

@ -1,66 +1,63 @@
"""Common plugin module."""
import logging
from typing import Iterable
from aiohttp import web
from aiohttp.web_routedef import AbstractRouteDef
from bumper import plugins
from bumper.models import RETURN_API_SUCCESS
from bumper.util import get_current_time_as_millis
from ... import WebserverPlugin
class v1_private_common(plugins.ConfServerApp):
def __init__(self):
self.name = "v1_private_common"
self.plugin_type = "sub_api"
self.sub_api = "api_v1"
self.routes = [
class CommonPlugin(WebserverPlugin):
"""Common plugin."""
@property
def routes(self) -> Iterable[AbstractRouteDef]:
"""Plugin routes."""
return [
web.route(
"*",
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/checkAPPVersion",
"/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/checkAPPVersion",
self.handle_checkAPPVersion,
name="v1_common_checkAppVersion",
),
web.route(
"*",
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/checkVersion",
"/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/checkVersion",
self.handle_checkVersion,
name="v1_common_checkVersion",
),
web.route(
"*",
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/uploadDeviceInfo",
"/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/uploadDeviceInfo",
self.handle_uploadDeviceInfo,
name="v1_common_uploadDeviceInfo",
),
web.route(
"*",
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/getSystemReminder",
"/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/getSystemReminder",
self.handle_getSystemReminder,
name="v1_common_getSystemReminder",
),
web.route(
"*",
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/getConfig",
"/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/getConfig",
self.handle_getConfig,
name="v1_common_getConfig",
),
web.route(
"*",
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/getAreas",
"/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/getAreas",
self.handle_getAreas,
name="v1_common_getAreas",
),
web.route(
"*",
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/getAgreementURLBatch",
"/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/getAgreementURLBatch",
self.handle_getAgreementURLBatch,
name="v1_common_getAgreementURLBatch",
),
web.route(
"*",
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/getTimestamp",
"/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/getTimestamp",
self.handle_getTimestamp,
name="v1_common_getTimestamp",
),
]

View file

@ -1,30 +1,31 @@
import logging
from typing import Iterable
from aiohttp import web
from aiohttp.web_routedef import AbstractRouteDef
from bumper import plugins
from bumper.models import RETURN_API_SUCCESS
from bumper.util import get_current_time_as_millis
from ... import WebserverPlugin
class v1_private_message(plugins.ConfServerApp):
def __init__(self):
self.name = "v1_private_message"
self.plugin_type = "sub_api"
self.sub_api = "api_v1"
self.routes = [
class MessagePlugin(WebserverPlugin):
"""Message plugin."""
@property
def routes(self) -> Iterable[AbstractRouteDef]:
"""Plugin routes."""
return [
web.route(
"*",
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/message/hasUnreadMsg",
"/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/message/hasUnreadMsg",
self.handle_hasUnreadMessage,
name="v1_message_hasUnreadMsg",
),
web.route(
"*",
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/message/getMsgList",
"/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/message/getMsgList",
self.handle_getMsgList,
name="v1_message_getMsgList",
),
]

View file

@ -1,24 +1,27 @@
"""Shop plugin module."""
import logging
from typing import Iterable
from aiohttp import web
from aiohttp.web_routedef import AbstractRouteDef
from bumper import plugins
from bumper.models import RETURN_API_SUCCESS
from bumper.util import get_current_time_as_millis
from ... import WebserverPlugin
class v1_private_shop(plugins.ConfServerApp):
def __init__(self):
self.name = "v1_private_shop"
self.plugin_type = "sub_api"
self.sub_api = "api_v1"
self.routes = [
class ShopPlugin(WebserverPlugin):
"""Shop plugin."""
@property
def routes(self) -> Iterable[AbstractRouteDef]:
"""Plugin routes."""
return [
web.route(
"*",
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/shop/getCnWapShopConfig",
"/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/shop/getCnWapShopConfig",
self.handle_getCnWapShopConfig,
name="v1_shop_getCnWapShopConfig",
),
]

View file

@ -1,89 +1,80 @@
import logging
from typing import Iterable
from aiohttp import web
from aiohttp.web_routedef import AbstractRouteDef
from bumper import plugins
from bumper.models import RETURN_API_SUCCESS
from bumper.util import get_current_time_as_millis
from bumper.web import auth_util
from ... import WebserverPlugin
class v1_private_user(plugins.ConfServerApp):
def __init__(self):
self.name = "v1_private_user"
self.plugin_type = "sub_api"
self.sub_api = "api_v1"
class UserPlugin(WebserverPlugin):
"""User plugin."""
self.routes = [
@property
def routes(self) -> Iterable[AbstractRouteDef]:
"""Plugin routes."""
return [
web.route(
"*",
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/login",
"/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/login",
auth_util.login,
name="v1_user_login",
),
web.route(
"*",
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkLogin",
"/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkLogin",
auth_util.login,
name="v1_user_checkLogin",
),
web.route(
"*",
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/getAuthCode",
"/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/getAuthCode",
auth_util.get_authcode,
name="v1_user_getAuthCode",
),
web.route(
"*",
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/logout",
"/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/logout",
auth_util.logout,
name="v1_user_logout",
),
web.route(
"*",
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkAgreement",
"/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkAgreement",
self.handle_checkAgreement,
name="v1_user_checkAgreement",
),
web.route(
"*",
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkAgreementBatch",
"/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkAgreementBatch",
self.handle_checkAgreement,
name="v1_user_checkAgreementBatch",
),
web.route(
"*",
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/getUserAccountInfo",
"/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/getUserAccountInfo",
auth_util.get_user_account_info,
name="v1_user_getUserAccountInfo",
),
web.route(
"*",
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/getUserMenuInfo",
"/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/getUserMenuInfo",
self.handle_getUserMenuInfo,
name="v1_user_getUserMenuInfo",
),
web.route(
"*",
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/changeArea",
"/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/changeArea",
self.handle_changeArea,
name="v1_user_changeArea",
),
web.route(
"*",
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/queryChangeArea",
"/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/queryChangeArea",
self.handle_changeArea,
name="v1_user_queryChangeArea",
),
web.route(
"*",
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/acceptAgreementBatch",
"/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/acceptAgreementBatch",
self.handle_acceptAgreementBatch,
name="v1_user_acceptAgreementBatch",
),
# Direct register from app:
# /{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/directRegister
# /{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/directRegister
# Register by email
# /registerByEmail
]

View file

@ -1,25 +1,28 @@
"""user setting plugin module."""
import logging
from typing import Iterable
from aiohttp import web
from aiohttp.web_routedef import AbstractRouteDef
from bumper import plugins
from bumper.models import RETURN_API_SUCCESS
from bumper.util import get_current_time_as_millis
from ... import WebserverPlugin
class v1_private_userSetting(plugins.ConfServerApp):
def __init__(self):
self.name = "v1_private_userSetting"
self.plugin_type = "sub_api"
self.sub_api = "api_v1"
class UserSettingPlugin(WebserverPlugin):
"""User setting plugin."""
self.routes = [
@property
def routes(self) -> Iterable[AbstractRouteDef]:
"""Plugin routes."""
return [
web.route(
"*",
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/userSetting/getSuggestionSetting",
"/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/userSetting/getSuggestionSetting",
self.handle_getSuggestionSetting,
name="v1_userSetting_getSuggestionSetting",
),
]