diff --git a/README.md b/README.md index 6944a89..f0bf07a 100644 --- a/README.md +++ b/README.md @@ -96,4 +96,4 @@ server { } } -``` \ No newline at end of file +``` diff --git a/models/__init__.py b/models/__init__.py index e69de29..82da278 100644 --- a/models/__init__.py +++ b/models/__init__.py @@ -0,0 +1 @@ +from .user import * \ No newline at end of file diff --git a/models/base.py b/models/base.py new file mode 100644 index 0000000..9bab4ed --- /dev/null +++ b/models/base.py @@ -0,0 +1,49 @@ +import hashlib +from pydantic import Field + +from pydantic import BaseModel, validator + +from settings import settings + +from ipaddress import IPv4Address + +FIELD_MAP = { + 'ip': 'a01', + 'os': 'a08', +} + + +def to_alias(k: str) -> str: + return FIELD_MAP.get(k) or k + + +class IP4(str): + + @classmethod + def __get_validators__(cls): + yield cls.validate + + @classmethod + def validate(cls, v): + IPv4Address(v) + return str(v) + + +class Base(BaseModel): + # sign = md5(distinct_id+account_id+act+ts+salt) + distinct_id: str = Field(..., title='访客 ID') + game: str + account_id: str + act: str + event_name: str = None + # preset: dict + properties: dict + ts: int + sign: str + + @validator('sign') + def sign_validator(cls, v: str, values: dict): + s = f'{values.get("distinct_id")}{values.get("account_id", "")}{values.get("act", "")}{values.get("ts", "")}{settings.SALT}' + if hashlib.md5(s.encode()).hexdigest() == v: + return v + raise ValueError(f'打击违法犯罪行为{hashlib.md5(s.encode()).hexdigest()}') diff --git a/models/event.py b/models/event.py new file mode 100644 index 0000000..e69de29 diff --git a/models/user.py b/models/user.py new file mode 100644 index 0000000..4196333 --- /dev/null +++ b/models/user.py @@ -0,0 +1,28 @@ +from pydantic import BaseModel + + +from .base import Base, IP4, to_alias + +__all__ = ('UserModel',) + + +class Preset(BaseModel): + ip: IP4 + os: str + ttt: str = None + + def dict(self, **kwargs): + res = super().dict(**kwargs) + return {'#' + k: v for k, v in res.items() if v is not None} + + class Config: + alias_generator = to_alias + + +class UserModel(Base): + preset: Preset + + def dict(self, **kwargs): + kwargs.setdefault('exclude', {'preset'}) + self.properties.update(self.preset.dict(**kwargs)) + return super().dict(**kwargs) diff --git a/routers/event.py b/routers/event.py new file mode 100644 index 0000000..e69de29 diff --git a/routers/user.py b/routers/user.py new file mode 100644 index 0000000..5b8d4e6 --- /dev/null +++ b/routers/user.py @@ -0,0 +1,29 @@ +import asyncio +import hashlib + +from fastapi import APIRouter, Request +from pydantic import BaseModel, validator + +from handler_data import HandlerUser, HandlerEvent +from settings import settings + +router = APIRouter() +from models import UserModel + + +@router.post("/user/") +async def user(request: Request, item: UserModel): + ta = getattr(request.app.state.ta, item.act) + # 将不同游戏发送到不同 topic_name + request.app.state.ta.consumer.topic_name = item.game + rdb = request.app.state.redis + await asyncio.gather(*map(lambda o: asyncio.create_task(o(rdb, item)), HandlerUser.handler_link)) + + ta(item.distinct_id, item.account_id, item.properties) + results = {"code": 0, 'msg': 'ok'} + return results + + + + +