diff --git a/api/api_v1/endpoints/data_auth.py b/api/api_v1/endpoints/data_auth.py index e8e67cf..8846985 100644 --- a/api/api_v1/endpoints/data_auth.py +++ b/api/api_v1/endpoints/data_auth.py @@ -1,7 +1,12 @@ +import json + import pymongo +from bson import ObjectId from fastapi import APIRouter, Depends, Request from fastapi.encoders import jsonable_encoder from motor.motor_asyncio import AsyncIOMotorDatabase +from redis import Redis + import crud, schemas from core.config import settings from core.security import get_password_hash @@ -9,6 +14,7 @@ from core.security import get_password_hash from db import get_database from api import deps from db.ckdb import CKDrive, get_ck_db +from db.redisdb import get_redis_pool, RedisDrive from utils import casbin_enforcer router = APIRouter() @@ -29,7 +35,7 @@ async def add_data_auth(request: Request, @router.post('/edit_data_auth') async def edit_data_auth(request: Request, data_id: schemas.DataAuthEdit, - game: str = Depends(deps.get_game_project), + game: str, db: AsyncIOMotorDatabase = Depends(get_database), current_user: schemas.UserDB = Depends(deps.get_current_user) ) -> schemas.Msg: @@ -40,7 +46,7 @@ async def edit_data_auth(request: Request, @router.get('/all_event') async def all_event(request: Request, - game: str = Depends(deps.get_game_project), + game: str, ck: CKDrive = Depends(get_ck_db), db: AsyncIOMotorDatabase = Depends(get_database), current_user: schemas.UserDB = Depends(deps.get_current_user) @@ -53,8 +59,8 @@ async def all_event(request: Request, @router.get("/list") async def data_authority(request: Request, + game: str, db: AsyncIOMotorDatabase = Depends(get_database), - game: str = Depends(deps.get_game_project), ck: CKDrive = Depends(get_ck_db), current_user: schemas.UserDB = Depends(deps.get_current_user) ) -> schemas.Msg: @@ -66,6 +72,63 @@ async def data_authority(request: Request, del item['_id'] item['data_range'] = f'{len(item["data"])}/{total_event}' - data = jsonable_encoder(data) return schemas.Msg(code=0, msg='ok', data=data) + + +@router.get("/my_event") +async def my_event(request: Request, + game: str, + db: AsyncIOMotorDatabase = Depends(get_database), + rdb: RedisDrive = Depends(get_redis_pool), + ck: CKDrive = Depends(get_ck_db), + current_user: schemas.UserDB = Depends(deps.get_current_user) + ) -> schemas.Msg: + """获取自己的事件权限""" + + # data_auth_id = await crud.authority.get_data_auth_id(db, game, request.user.username) + data_auth_id = await crud.authority.get_data_auth_id(db, game, 'sddfdaa') + my_data_auth = await crud.data_auth.get(db, ObjectId(data_auth_id)) + + all_filed = await rdb.get(f'{game}_event') + all_filed = json.loads(all_filed) + data_attr = await crud.data_attr.find_many(db, game=game, cat='event') + data_attr = {item['name']: item for item in data_attr} + + if not my_data_auth: + return schemas.Msg(code=0, msg='ok', data=[]) + key_prefix = f'{game}_event_' + + event_dict = await rdb.smembers_keys(*my_data_auth['data'], prefix=key_prefix) + res = [] + for k, v in event_dict.items(): + event_attr = [] + event_filter = [] + for item in v: + data_type = settings.CK_TYPE_DICT.get(all_filed.get(item)) + title = data_attr.get(item, {}).get('show_name') or item + event_attr.append( + { + 'id': item, + 'data_type': data_type, + 'title': title, + 'category': settings.CK_OPERATOR.get(data_type) or [] + } + ) + event_filter.append({ + 'id': item, + 'data_type': data_type, + 'title': title, + 'category': settings.CK_FILTER.get(data_type) or [] + }) + res.append({ + 'event_name': k, + 'event_attr': [{'id': 'event', 'title': '事件属性', 'category': event_attr}], + 'event_filter': [{'id': 'event', 'title': '事件属性', 'category': event_filter}], + } + ) + + return schemas.Msg(code=0, msg='ok', data=[{'id': 'event', + 'title': '默认分组', + 'category': res + }]) diff --git a/core/config.py b/core/config.py index 0c31cab..9233485 100644 --- a/core/config.py +++ b/core/config.py @@ -42,8 +42,8 @@ class Settings(BaseSettings): "Nullable(DateTime('UTC'))": 'datetime', "DateTime()": 'datetime', - "Nullable(IPv4)": 'ip', - "IPv4": 'ip', + "Nullable(IPv4)": 'string', + "IPv4": 'string', "String": 'string', "Nullable(String)": 'string', @@ -74,15 +74,176 @@ class Settings(BaseSettings): "Nullable(Float)": 'float', "Float": 'float', } + CK_OPERATOR = { + 'int': [{ + 'id': 'sum', + 'title': '总和' + }, { + 'id': 'avg', + 'title': '均值' + }, { + 'id': 'median', + 'title': '中位数' + }, { + 'id': 'max', + 'title': '最大值' + }, { + 'id': 'min', + 'title': '最小值' + }, { + 'id': 'distinct', + 'title': '去重数' + }, + + ], + 'string': [{ + 'id': 'distinct', + 'title': '去重数' + }], + 'float': [{ + 'id': 'sum', + 'title': '总和' + }, { + 'id': 'avg', + 'title': '均值' + }, { + 'id': 'median', + 'title': '中位数' + }, { + 'id': 'max', + 'title': '最大值' + }, { + 'id': 'min', + 'title': '最小值' + }, { + 'id': 'distinct', + 'title': '去重数' + }, + + ], + 'array': [ + { + 'id': 'distinct1', + 'title': '列表去重数' + }, + { + 'id': 'distinct2', + 'title': '集合去重数' + }, + { + 'id': 'distinct3', + 'title': '元素去重数' + }, + ] + } + + CK_FILTER = { + 'int': [{ + 'id': '=', + 'title': '等于' + }, { + 'id': '!=', + 'title': '不等于' + }, { + 'id': '<', + 'title': '小于' + }, { + 'id': '>', + 'title': '大于' + }, { + 'id': 'not null', + 'title': '有值' + }, { + 'id': 'is null', + 'title': '无值' + }, { + 'id': 'range', + 'title': '区间' + }, + ], + 'string': [{ + 'id': '=', + 'title': '等于' + }, { + 'id': '!=', + 'title': '不等于' + }, { + 'id': 'in', + 'title': '包括' + }, { + 'id': 'not in', + 'title': '不包括' + }, { + 'id': 'not null', + 'title': '有值' + }, { + 'id': 'is null', + 'title': '无值' + }, { + 'id': 'regex', + 'title': '正则匹配' + }, { + 'id': 'not regex', + 'title': '正则不匹配' + }, + ], + 'float': [{ + 'id': '=', + 'title': '等于' + }, { + 'id': '!=', + 'title': '不等于' + }, { + 'id': '<', + 'title': '小于' + }, { + 'id': '>', + 'title': '大于' + }, { + 'id': 'not null', + 'title': '有值' + }, { + 'id': 'is null', + 'title': '无值' + }, { + 'id': 'range', + 'title': '区间' + }, ], + 'datetime': [ + { + 'id': '=', + 'title': '绝对时间' + }, + { + 'id': '=', + 'title': '相对当前日期' + }, + { + 'id': '=', + 'title': '相对事件发生时刻' + }, + { + 'id': '=', + 'title': '有值' + }, + { + 'id': '=', + 'title': '无值' + }, + ], + } + class Config: case_sensitive = True class Debug(Settings): REDIS_CONF = { - 'address': ('139.159.159.3', 6378), + 'host': '139.159.159.3', + 'port': 6378, 'password': 'd1Gh*zp5', - 'db': 1 + 'db': 1, + 'decode_responses': 'utf-8', } diff --git a/crud/crud_authority.py b/crud/crud_authority.py index 45550bb..641d0a5 100644 --- a/crud/crud_authority.py +++ b/crud/crud_authority.py @@ -74,6 +74,10 @@ class CRUDAuthority(CRUDBase): async def get_all_user(self, db: AsyncIOMotorDatabase): return await self.distinct(db, 'v0', {'ptype': 'g'}) + async def get_data_auth_id(self, db, game, username): + res = await self.find_one(db, {'ptype': 'g', 'v0': username, 'v2': game}, {'_id': 0, 'data_auth_id': 1}) + return res.get('data_auth_id') + async def create_index(self, db: AsyncIOMotorDatabase): await db[self.coll_name].create_index( [('ptype', pymongo.DESCENDING), ('v0', pymongo.DESCENDING), ('v1', pymongo.DESCENDING), diff --git a/db/redisdb.py b/db/redisdb.py index 21d92a2..f28d0c8 100644 --- a/db/redisdb.py +++ b/db/redisdb.py @@ -1,12 +1,32 @@ -from aioredis import create_redis_pool, Redis +from aredis import StrictRedis +import asyncio -class RedisBase: - client: Redis = None +class RedisDrive: + client: StrictRedis = None + + # async def get_keys(self, *keys, prefix='') -> list: + # res = [] + # for key in keys: + # key = prefix + key + # data = await self.client.get(key, encoding='utf8') + # res.append(data) + # return res + + async def smembers_keys(self, *keys, prefix='') -> dict: + tasks = [] + for key in keys: + task = asyncio.create_task(self.client.smembers(prefix + key)) + tasks.append(task) + data = await asyncio.gather(*tasks) + return {k: v for k, v in zip(keys, data)} + + def __getattr__(self, item): + return getattr(self.client, item) -rdb = RedisBase() +rdb = RedisDrive() -def get_redis_pool() -> Redis: - return rdb.client +def get_redis_pool() -> RedisDrive: + return rdb diff --git a/db/redisdb_utils.py b/db/redisdb_utils.py index 6ad1237..1a6cb48 100644 --- a/db/redisdb_utils.py +++ b/db/redisdb_utils.py @@ -1,14 +1,12 @@ -import aioredis -from aioredis import create_redis_pool, Redis +from aredis import StrictRedis from core.config import settings -from .redisdb import rdb +from .redisdb import RedisDrive async def connect_to_redis(): - rdb.client = await create_redis_pool(**settings.REDIS_CONF) + RedisDrive.client = StrictRedis(**settings.REDIS_CONF) async def close_redis_connection(): - rdb.client.close() - await rdb.client.wait_closed() + pass diff --git a/main.py b/main.py index ebb16a0..a0a5b37 100644 --- a/main.py +++ b/main.py @@ -1,7 +1,8 @@ import binascii +import time import uvicorn -from fastapi import FastAPI +from fastapi import FastAPI, Request from starlette.middleware.cors import CORSMiddleware from starlette.authentication import AuthenticationBackend, AuthenticationError, AuthCredentials, BaseUser, SimpleUser from starlette.middleware.authentication import AuthenticationMiddleware @@ -72,5 +73,15 @@ app.add_middleware( allow_headers=["*"], ) + +@app.middleware("http") +async def add_process_time_header(request: Request, call_next): + start_time = int(time.time()*1000) + response = await call_next(request) + process_time = int(time.time()*1000) - start_time + response.headers["X-Process-Time"] = str(process_time) + return response + + if __name__ == '__main__': - uvicorn.run(app='main:app', host="0.0.0.0", port=8889, reload=True, debug=True) + uvicorn.run(app='main:app', host="0.0.0.0", port=7889, reload=True, debug=True)