update
This commit is contained in:
parent
029b88c5cd
commit
6e677eda58
4
main.py
4
main.py
@ -3,7 +3,7 @@ from aioredis import create_redis_pool
|
||||
from fastapi import FastAPI
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
|
||||
from routers import point
|
||||
from routers import point, user, event
|
||||
from settings import settings
|
||||
|
||||
from utils.ta_sdk import TGAnalytics, ToKafka
|
||||
@ -36,6 +36,8 @@ def register_ta(app: FastAPI) -> None:
|
||||
|
||||
|
||||
app.include_router(point.router, prefix='/v1')
|
||||
app.include_router(user.router, prefix='/v1')
|
||||
app.include_router(event.router, prefix='/v1')
|
||||
register_redis(app)
|
||||
register_ta(app)
|
||||
|
||||
|
@ -1 +1,2 @@
|
||||
from .user import *
|
||||
from .event import *
|
@ -1,4 +1,6 @@
|
||||
import hashlib
|
||||
from enum import Enum
|
||||
|
||||
from pydantic import Field
|
||||
|
||||
from pydantic import BaseModel, validator
|
||||
@ -8,8 +10,52 @@ from settings import settings
|
||||
from ipaddress import IPv4Address
|
||||
|
||||
FIELD_MAP = {
|
||||
'user_id': 'x01',
|
||||
'account_id': 'x02',
|
||||
'distinct_id': 'x03',
|
||||
'event_name': 'x04',
|
||||
'server_time':'x05',
|
||||
|
||||
'ip': 'a01',
|
||||
'country': 'a02',
|
||||
'country_code': 'a03',
|
||||
'province': 'a04',
|
||||
'city': 'a05',
|
||||
'os_version': 'a06',
|
||||
'manufacturer': 'a07',
|
||||
'os': 'a08',
|
||||
'device_id': 'a09',
|
||||
'screen_height': 'a10',
|
||||
'screen_width': 'a11',
|
||||
'device_model': 'a12',
|
||||
'app_version': 'a13',
|
||||
'bundle_id': 'a14',
|
||||
'lib': 'a15',
|
||||
'lib_version': 'a16',
|
||||
'network_type': 'a17',
|
||||
'carrier': 'a18',
|
||||
'browser': 'a19',
|
||||
'browser_version': 'a20',
|
||||
'duration': 'a21',
|
||||
'url': 'a22',
|
||||
'url_path': 'a23',
|
||||
'referrer': 'a24',
|
||||
'referrer_host': 'a25',
|
||||
'title': 'a26',
|
||||
'screen_name': 'a27',
|
||||
'element_id': 'a28',
|
||||
'element_type': 'a29',
|
||||
'resume_from_background': 'a30',
|
||||
'element_selector': 'a31',
|
||||
'element_position': 'a32',
|
||||
'element_content': 'a33',
|
||||
'scene': 'a34',
|
||||
'mp_platform': 'a35',
|
||||
'app_crashed_reason': 'a36',
|
||||
'zone_offset': 'a37',
|
||||
|
||||
'app_id':'b01',
|
||||
'event_time':'b06'
|
||||
}
|
||||
|
||||
|
||||
@ -29,21 +75,33 @@ class IP4(str):
|
||||
return str(v)
|
||||
|
||||
|
||||
class ActEnum(str, Enum):
|
||||
track = 'track'
|
||||
user_set = 'user_set'
|
||||
user_setOnce = 'user_setOnce'
|
||||
user_add = 'user_add'
|
||||
user_unset = 'user_unset'
|
||||
user_append = 'user_append'
|
||||
user_del = 'user_del'
|
||||
|
||||
|
||||
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
|
||||
# sign = md5(game+act+ts+salt)
|
||||
game: str = Field(..., title='游戏代号')
|
||||
act: ActEnum = Field(..., title='操作', description='同ta一致')
|
||||
preset: BaseModel
|
||||
properties: dict = Field(..., title='自定义属性')
|
||||
ts: int = Field(..., title='时间戳')
|
||||
sign: str = Field(..., title='签名')
|
||||
|
||||
@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}'
|
||||
s = f'{values.get("game", "")}{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()}')
|
||||
raise ValueError(f'sign {hashlib.md5(s.encode()).hexdigest()}')
|
||||
|
||||
def dict(self, **kwargs):
|
||||
kwargs.setdefault('exclude', {'preset', 'account_id', 'distinct_id', 'event_name'})
|
||||
self.properties.update(self.preset.dict(**kwargs))
|
||||
return super().dict(**kwargs)
|
||||
|
@ -0,0 +1,70 @@
|
||||
from datetime import datetime
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from .base import Base, IP4, to_alias
|
||||
|
||||
__all__ = ('EventModel',)
|
||||
|
||||
|
||||
class Preset(BaseModel):
|
||||
ip: IP4 = Field(None, title='ipv4',description='不传该字段默认使用源ip')
|
||||
country: str = Field(None, title='国家',description='')
|
||||
country_code: str = Field(None, title='国家代码',description='')
|
||||
province: str = Field(None, title='省份',description='')
|
||||
city: str = Field(None, title='城市',description='')
|
||||
os_version: str = Field(None, title='操作系统版本',description='')
|
||||
manufacturer: str = Field(None, title='设备制造商',description='')
|
||||
os: str = Field(None, title='操作系统',description='')
|
||||
device_id: str = Field(None, title='设备 ID',description='')
|
||||
screen_height: int = Field(None, title='屏幕高度',description='')
|
||||
screen_width: int = Field(None, title='屏幕宽度',description='')
|
||||
device_model: str = Field(None, title='设备型号',description='')
|
||||
app_version: str = Field(None, title='APP 版本',description='')
|
||||
bundle_id: str = Field(None, title='APP包名',description='')
|
||||
lib: str = Field(None, title='SDK 类型',description='')
|
||||
lib_version: str = Field(None, title='SDK 版本',description='')
|
||||
network_type: str = Field(None, title='网络状态',description='')
|
||||
carrier: str = Field(None, title='网络运营商',description='')
|
||||
browser: str = Field(None, title='浏览器类型',description='')
|
||||
browser_version: str = Field(None, title='浏览器版本',description='')
|
||||
duration: int = Field(None, title='事件时长',description='')
|
||||
url: str = Field(None, title='页面地址',description='')
|
||||
url_path: str = Field(None, title='页面路径',description='')
|
||||
referrer: str = Field(None, title='前向地址',description='')
|
||||
referrer_host: str = Field(None, title='前向路径',description='')
|
||||
title: str = Field(None, title='页面标题',description='')
|
||||
screen_name: str = Field(None, title='页面名称',description='')
|
||||
element_id: str = Field(None, title='元素 ID',description='')
|
||||
element_type: str = Field(None, title='元素类型',description='')
|
||||
resume_from_background: str = Field(None, title='是否从后台唤醒',description='')
|
||||
element_selector: str = Field(None, title='元素选择器',description='')
|
||||
element_position: str = Field(None, title='元素位置',description='')
|
||||
element_content: str = Field(None, title='元素内容',description='')
|
||||
scene: str = Field(None, title='场景值',description='')
|
||||
mp_platform: str = Field(None, title='小程序平台',description='')
|
||||
app_crashed_reason: str = Field(None, title='异常信息',description='')
|
||||
zone_offset: str = Field(None, title='时区偏移',description='')
|
||||
|
||||
user_id: str = Field(..., title='用户唯一 ID',description='')
|
||||
account_id: str = Field(..., title='账户 ID', description='')
|
||||
distinct_id: str = Field(..., title='访客 ID',description='')
|
||||
event_name: str = Field(..., title='事件名称',description='')
|
||||
|
||||
# 事件
|
||||
app_id: str = Field(None, description='')
|
||||
event_time: datetime = Field(None,title='事件时间', description='')
|
||||
server_time: datetime = Field(None,title='服务端时间', description='')
|
||||
|
||||
|
||||
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 EventModel(Base):
|
||||
preset: Preset = Field(..., title='系统属性')
|
||||
|
@ -1,5 +1,6 @@
|
||||
from pydantic import BaseModel
|
||||
from datetime import datetime
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from .base import Base, IP4, to_alias
|
||||
|
||||
@ -7,9 +8,51 @@ __all__ = ('UserModel',)
|
||||
|
||||
|
||||
class Preset(BaseModel):
|
||||
ip: IP4
|
||||
os: str
|
||||
ttt: str = None
|
||||
ip: IP4 = Field(None, title='ipv4', description='不传该字段默认使用源ip')
|
||||
country: str = Field(None, title='国家', description='')
|
||||
country_code: str = Field(None, title='国家代码', description='')
|
||||
province: str = Field(None, title='省份', description='')
|
||||
city: str = Field(None, title='城市', description='')
|
||||
os_version: str = Field(None, title='操作系统版本', description='')
|
||||
manufacturer: str = Field(None, title='设备制造商', description='')
|
||||
os: str = Field(None, title='操作系统', description='')
|
||||
device_id: str = Field(None, title='设备 ID', description='')
|
||||
screen_height: int = Field(None, title='屏幕高度', description='')
|
||||
screen_width: int = Field(None, title='屏幕宽度', description='')
|
||||
device_model: str = Field(None, title='设备型号', description='')
|
||||
app_version: str = Field(None, title='APP 版本', description='')
|
||||
bundle_id: str = Field(None, title='APP包名', description='')
|
||||
lib: str = Field(None, title='SDK 类型', description='')
|
||||
lib_version: str = Field(None, title='SDK 版本', description='')
|
||||
network_type: str = Field(None, title='网络状态', description='')
|
||||
carrier: str = Field(None, title='网络运营商', description='')
|
||||
browser: str = Field(None, title='浏览器类型', description='')
|
||||
browser_version: str = Field(None, title='浏览器版本', description='')
|
||||
duration: int = Field(None, title='事件时长', description='')
|
||||
url: str = Field(None, title='页面地址', description='')
|
||||
url_path: str = Field(None, title='页面路径', description='')
|
||||
referrer: str = Field(None, title='前向地址', description='')
|
||||
referrer_host: str = Field(None, title='前向路径', description='')
|
||||
title: str = Field(None, title='页面标题', description='')
|
||||
screen_name: str = Field(None, title='页面名称', description='')
|
||||
element_id: str = Field(None, title='元素 ID', description='')
|
||||
element_type: str = Field(None, title='元素类型', description='')
|
||||
resume_from_background: str = Field(None, title='是否从后台唤醒', description='')
|
||||
element_selector: str = Field(None, title='元素选择器', description='')
|
||||
element_position: str = Field(None, title='元素位置', description='')
|
||||
element_content: str = Field(None, title='元素内容', description='')
|
||||
scene: str = Field(None, title='场景值', description='')
|
||||
mp_platform: str = Field(None, title='小程序平台', description='')
|
||||
app_crashed_reason: str = Field(None, title='异常信息', description='')
|
||||
zone_offset: str = Field(None, title='时区偏移', description='')
|
||||
|
||||
user_id: str = Field(..., title='用户唯一 ID', description='')
|
||||
account_id: str = Field(..., title='账户 ID', description='')
|
||||
distinct_id: str = Field(..., title='访客 ID', description='')
|
||||
# event_name: str = Field(..., title='事件名称',description='')
|
||||
|
||||
# 用户
|
||||
server_time: datetime = Field(None, title='服务端时间', description='')
|
||||
|
||||
def dict(self, **kwargs):
|
||||
res = super().dict(**kwargs)
|
||||
@ -20,9 +63,4 @@ class Preset(BaseModel):
|
||||
|
||||
|
||||
class UserModel(Base):
|
||||
preset: Preset
|
||||
|
||||
def dict(self, **kwargs):
|
||||
kwargs.setdefault('exclude', {'preset'})
|
||||
self.properties.update(self.preset.dict(**kwargs))
|
||||
return super().dict(**kwargs)
|
||||
preset: Preset = Field(..., title='系统属性')
|
||||
|
@ -0,0 +1,23 @@
|
||||
import asyncio
|
||||
|
||||
from fastapi import APIRouter, Request
|
||||
|
||||
from handler_data import HandlerEvent
|
||||
|
||||
router = APIRouter()
|
||||
from models import EventModel
|
||||
|
||||
|
||||
@router.post("/event/")
|
||||
async def event(request: Request, item: EventModel):
|
||||
item.preset.ip = item.preset.ip or request.client.host
|
||||
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)), HandlerEvent.handler_link))
|
||||
|
||||
properties = item.dict()['properties']
|
||||
ta(item.preset.distinct_id, item.preset.account_id, item.preset.event_name, properties)
|
||||
results = {"code": 0, 'msg': 'ok'}
|
||||
return results
|
@ -11,7 +11,7 @@ router = APIRouter()
|
||||
|
||||
|
||||
class Item(BaseModel):
|
||||
# sign = md5(distinct_id+account_id+act+ts+salt)
|
||||
# sign = md5(game+act+ts+salt)
|
||||
distinct_id: str
|
||||
game: str
|
||||
account_id: str
|
||||
@ -23,14 +23,15 @@ class Item(BaseModel):
|
||||
|
||||
@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}'
|
||||
s = f'{values.get("game")}{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()}')
|
||||
raise ValueError(f'签名 {hashlib.md5(s.encode()).hexdigest()}')
|
||||
|
||||
|
||||
@router.post("/point/")
|
||||
async def point(request: Request, item: Item):
|
||||
ip = request.client.host
|
||||
ta = getattr(request.app.state.ta, item.act)
|
||||
# 将不同游戏发送到不同 topic_name
|
||||
request.app.state.ta.consumer.topic_name = item.game
|
||||
@ -42,7 +43,7 @@ async def point(request: Request, item: Item):
|
||||
else:
|
||||
await asyncio.gather(*map(lambda o: asyncio.create_task(o(rdb, item)), HandlerUser.handler_link))
|
||||
await user_set(ta, item)
|
||||
results = {"code": 0, 'msg': 'ok'}
|
||||
results = {"code": 0, 'msg': 'ok','ip':ip}
|
||||
return results
|
||||
|
||||
|
||||
|
@ -1,11 +1,8 @@
|
||||
import asyncio
|
||||
import hashlib
|
||||
|
||||
from fastapi import APIRouter, Request
|
||||
from pydantic import BaseModel, validator
|
||||
|
||||
from handler_data import HandlerUser, HandlerEvent
|
||||
from settings import settings
|
||||
from handler_data import HandlerUser
|
||||
|
||||
router = APIRouter()
|
||||
from models import UserModel
|
||||
@ -13,17 +10,13 @@ from models import UserModel
|
||||
|
||||
@router.post("/user/")
|
||||
async def user(request: Request, item: UserModel):
|
||||
item.preset.ip = item.preset.ip or request.client.host
|
||||
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)
|
||||
properties = item.dict()['properties']
|
||||
ta(item.preset.distinct_id, item.preset.account_id, properties)
|
||||
results = {"code": 0, 'msg': 'ok'}
|
||||
return results
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,6 +1,3 @@
|
||||
import json
|
||||
|
||||
|
||||
class Config:
|
||||
REDIS_CONF = {
|
||||
'address': ('192.168.0.161', 6379),
|
||||
|
Loading…
Reference in New Issue
Block a user