Browse Source

multidevices support backend

main
gsd 4 months ago
parent
commit
78b8547e9d
  1. 83
      dbService.py
  2. 5
      service.py
  3. 25
      webExtensions/messageList.py
  4. 34
      webExtensions/nodeList.py
  5. 10
      webExtensions/packetEndpoint.py

83
dbService.py

@ -3,16 +3,56 @@ from pymongo.asynchronous.database import AsyncDatabase
from typing import List from typing import List
from entities.PacketGroup import PacketGroup from entities.PacketGroup import PacketGroup
from entities.PacketSignal import PacketSignal from entities.PacketSignal import PacketSignal
from pymongo import DESCENDING
class NodeDbService: class MultiDeviceDbSupport:
def __init__(self, dbStore, core): def __init__(self, dbStore, core):
self.dbStore:AsyncDatabase = dbStore self.dbStore:AsyncDatabase = dbStore
self.core = core self.core = core
#self.core.defaultDeviceUUID
async def listOfNodes(self): #return {"$or": [{"device_uuid": value}]}
def deviceHash2Match(self, devices_hashes = []):
if devices_hashes == None:
devices_hashes = [self.core.defaultDeviceUUID]
elif (type(devices_hashes) == list):
if devices_hashes.__len__() == 0:
devices_hashes = [self.core.defaultDeviceUUID]
else:
devices_hashes = [devices_hashes]
orPart = []
for hash in devices_hashes:
uuid = self.core.devicesUuidHashToUuid.get(hash, "")
if uuid:
if uuid == self.core.defaultDeviceUUID:
orPart.append({"device_uuid", None})
orPart.append({"device_uuid": uuid})
return orPart#-->{"$or": orPart}
class MessageDbService(MultiDeviceDbSupport):
def __init__(self, dbStore, core):
super().__init__(dbStore, core)
async def listOfMessage(self, limit:int, offset:int, after: float, before: float, devices = []):
collection = self.dbStore['packet']
payload = {
"to": int(self.core.PUB_CH),
"portnum":self.MESSAGE_PORTNUM,
"ts":{'$gt': after, "$lt": before},
"$or": self.deviceHash2Match(devices)
}
c = collection.find(payload).sort("ts", DESCENDING).skip(offset).limit(limit)
return await c.to_list()
class NodeDbService(MultiDeviceDbSupport):
def __init__(self, dbStore, core):
super().__init__(dbStore, core)
async def listOfNodes(self, devices = []):
pipeline = [ #ai slooop pipeline = [ #ai slooop
{"$match": {"device_uuid": self.core.defaultDeviceUUID}}, {"$match": {"$or": self.deviceHash2Match(devices)}},
# Сортировка для каждого num по убыванию ts # Сортировка для каждого num по убыванию ts
{"$sort": {"num": 1, "ts": -1}}, {"$sort": {"num": 1, "ts": -1}},
# Группировка по num и взятие первого (последнего) документа # Группировка по num и взятие первого (последнего) документа
@ -30,9 +70,9 @@ class NodeDbService:
c = await collection.aggregate(pipeline) c = await collection.aggregate(pipeline)
return await c.to_list() return await c.to_list()
async def listOfDirectNodes(self): async def listOfDirectNodes(self, devices = []):
pipeline = [ #ai slooop pipeline = [ #ai slooop
{"$match": {"hops_away": 0, "device_uuid": self.core.defaultDeviceUUID}}, # Фильтруем по списку {"$match": {"hops_away": 0, "$or": self.deviceHash2Match(devices)}}, # Фильтруем по списку
# Сортировка для каждого num по убыванию ts # Сортировка для каждого num по убыванию ts
{"$sort": {"num": 1, "ts": -1}}, {"$sort": {"num": 1, "ts": -1}},
# Группировка по num и взятие первого (последнего) документа # Группировка по num и взятие первого (последнего) документа
@ -50,17 +90,17 @@ class NodeDbService:
c = await collection.aggregate(pipeline) c = await collection.aggregate(pipeline)
return await c.to_list() return await c.to_list()
async def oneNode(self, num: int): async def oneNode(self, num: int, devices = []):
collection = self.dbStore['node_info'] collection = self.dbStore['node_info']
c = await collection.find_one( c = await collection.find_one(
{"num":int(num), "device_uuid": self.core.defaultDeviceUUID}, {"num":int(num), "$or": self.deviceHash2Match(devices)},
sort=[("ts", -1)] sort=[("ts", -1)]
) )
return c return c
async def listOfSelectedNodes(self, nums: List[int]): async def listOfSelectedNodes(self, nums: List[int], devices = []):
pipeline = [ pipeline = [
{"$match": {"num": {"$in": nums}, "device_uuid": self.core.defaultDeviceUUID}}, # Фильтруем по списку {"$match": {"num": {"$in": nums}, "$or": self.deviceHash2Match(devices)}}, # Фильтруем по списку
{"$sort": {"num": 1, "ts": -1}}, # Сортируем по num и ts (по убыванию) {"$sort": {"num": 1, "ts": -1}}, # Сортируем по num и ts (по убыванию)
{ {
"$group": { "$group": {
@ -75,9 +115,9 @@ class NodeDbService:
c = await collection.aggregate(pipeline) c = await collection.aggregate(pipeline)
return await c.to_list() return await c.to_list()
async def listOfFindLikeName(self, long_name): async def listOfFindLikeName(self, long_name, devices = []):
pipeline = [ pipeline = [
{"$match": {"long_name": {"$regex":long_name ,'$options' : 'i'}, "device_uuid": self.core.defaultDeviceUUID}}, # Фильтруем по списку {"$match": {"long_name": {"$regex":long_name ,'$options' : 'i'}, "$or": self.deviceHash2Match(devices)}}, # Фильтруем по списку
{"$sort": {"num": 1, "ts": -1}}, # Сортируем по num и ts (по убыванию) {"$sort": {"num": 1, "ts": -1}}, # Сортируем по num и ts (по убыванию)
{ {
"$group": { "$group": {
@ -92,17 +132,17 @@ class NodeDbService:
c = await collection.aggregate(pipeline) c = await collection.aggregate(pipeline)
return await c.to_list() return await c.to_list()
class PacketDbService: class PacketDbService(MultiDeviceDbSupport):
def __init__(self, dbStore, core): def __init__(self, dbStore, core):
self.dbStore:AsyncDatabase = dbStore super().__init__(dbStore, core)
self.core = core
async def findPacketsSignals(self, async def findPacketsSignals(self,
after: float = -1, after: float = -1,
before: float = -1, before: float = -1,
nums: List[int] = []): nums: List[int] = [],
devices = []):
pipeline = [] pipeline = []
match = {"device_uuid": self.core.defaultDeviceUUID} match = {"$or": self.deviceHash2Match(devices)}
if after != -1 or before != -1: if after != -1 or before != -1:
match["ts"] = {} match["ts"] = {}
if after != -1: if after != -1:
@ -127,10 +167,11 @@ class PacketDbService:
nums: List[int] = [], nums: List[int] = [],
portnums: List[int] = [], portnums: List[int] = [],
packetsPerNode = False, packetsPerNode = False,
packetsSumNode = False): packetsSumNode = False,
devices = []):
pipeline = [] pipeline = []
match = {} match = {"$or": self.deviceHash2Match(devices)}
if after != -1 or before != -1: if after != -1 or before != -1:
match["ts"] = {} match["ts"] = {}
if after != -1: if after != -1:
@ -149,7 +190,6 @@ class PacketDbService:
match["portnums"] = {"$in":portnums} match["portnums"] = {"$in":portnums}
if match: if match:
match.update({"device_uuid": self.core.defaultDeviceUUID})
pipeline.append({"$match":match}) pipeline.append({"$match":match})
#групировка по количеству на выхлопе _id номер портнума и count число его юзов #групировка по количеству на выхлопе _id номер портнума и count число его юзов
@ -175,8 +215,9 @@ class PacketDbService:
l = await c.to_list() l = await c.to_list()
return [PacketGroup(p, packetsPerNode, packetsSumNode) for p in l] return [PacketGroup(p, packetsPerNode, packetsSumNode) for p in l]
class DbService(NodeDbService, PacketDbService): class DbService(NodeDbService, PacketDbService, MessageDbService):
def __init__(self, dbStore, core): def __init__(self, dbStore, core):
NodeDbService.__init__(self, dbStore, core) NodeDbService.__init__(self, dbStore, core)
PacketDbService.__init__(self, dbStore, core) PacketDbService.__init__(self, dbStore, core)
MessageDbService.__init__(self, dbStore, core)

5
service.py

@ -30,7 +30,7 @@ from dbService import DbService
#other #other
from botManager import BotManager from botManager import BotManager
from utils import isInt, generate_random_string from utils import isInt, generate_random_string, md5hash
class MeshArgsParse: class MeshArgsParse:
def __init__(self, args): def __init__(self, args):
@ -41,6 +41,7 @@ class MeshMultiListener(MeshArgsParse):
self.PUB_CH = PUB_CH self.PUB_CH = PUB_CH
super().__init__(args) super().__init__(args)
self.devices:List[MeshtDevice] = [] self.devices:List[MeshtDevice] = []
self.devicesUuidHashToUuid = {}
self.defaultDeviceUUID = "" self.defaultDeviceUUID = ""
self.readConfig(args.change_workdir, args.mesh_config) self.readConfig(args.change_workdir, args.mesh_config)
@ -91,6 +92,8 @@ class MeshMultiListener(MeshArgsParse):
#set default mesh #set default mesh
self.defaultDeviceUUID = self.json_config[0]["uuid"] self.defaultDeviceUUID = self.json_config[0]["uuid"]
for device in self.devices:
self.devicesUuidHashToUuid[md5hash(device.device_uuid)] = device.device_uuid
async def meshListener(self, device: MeshtDevice, queue: asyncio.Queue): async def meshListener(self, device: MeshtDevice, queue: asyncio.Queue):
run = not self.args.disable_mesh or self.args.enable_mesh run = not self.args.disable_mesh or self.args.enable_mesh

25
webExtensions/messageList.py

@ -6,7 +6,6 @@ from fastapi import Query
from pymongo.asynchronous.database import AsyncDatabase from pymongo.asynchronous.database import AsyncDatabase
from extra.MessageDTO import MessageDTO from extra.MessageDTO import MessageDTO
from typing import List, Annotated from typing import List, Annotated
from pymongo import DESCENDING
class WebExtension: class WebExtension:
MESSAGE_PORTNUM = 1 MESSAGE_PORTNUM = 1
@ -15,19 +14,19 @@ class WebExtension:
def __init__(self, core): def __init__(self, core):
self.core = core self.core = core
self.app = core.app self.app = core.app
self.dbStore = core.dbStore self.dbService = core.dbService
@self.app.get(f"{self.core.context}/messages") @self.app.get(f"{self.core.context}/messages")
@self.core.authManager.authRequest() @self.core.authManager.authRequest()
async def listOfMessages(request: Request, limit: int = Query(10), offset: int = Query(0), after: float = Query(0), before: float = Query(0)): async def listOfMessages(
collection = self.dbStore['packet'] request: Request,
limit: int = Query(10),
payload = { offset: int = Query(0),
"to": int(self.core.PUB_CH), after: float = Query(0),
"portnum":self.MESSAGE_PORTNUM, before: float = Query(0),
"ts":{'$gt': after, "$lt": before} devices: List[str] = Query([])
} ):
l = await self.dbService.listOfMessage(
c = collection.find(payload).sort("ts", DESCENDING).skip(offset).limit(limit) limit, offset, after, before, devices
l = await c.to_list() )
return [MessageDTO(msg) for msg in l] return [MessageDTO(msg) for msg in l]

34
webExtensions/nodeList.py

@ -17,25 +17,35 @@ class WebExtension:
@self.app.get(f"{self.core.context}/nodes/list") @self.app.get(f"{self.core.context}/nodes/list")
@self.core.authManager.authRequest() @self.core.authManager.authRequest()
async def listOfNodes(request: Request, p: bool = Query(False), m:bool = Query(False)): async def listOfNodes(request: Request,
l = await self.dbService.listOfNodes() p: bool = Query(False),
m:bool = Query(False),
devices: List[str] = Query([])):
l = await self.dbService.listOfNodes(devices)
return [NodeDTO(node, p, m) for node in l] return [NodeDTO(node, p, m) for node in l]
@self.app.get(f"{self.core.context}/nodes/direct") @self.app.get(f"{self.core.context}/nodes/direct")
@self.core.authManager.authRequest() @self.core.authManager.authRequest()
async def listOfDirectNodes(request: Request, p: bool = Query(False), m:bool = Query(False)): async def listOfDirectNodes(request: Request,
l = await self.dbService.listOfDirectNodes() p: bool = Query(False),
m:bool = Query(False),
devices: List[str] = Query([])):
l = await self.dbService.listOfDirectNodes(devices)
return [NodeDTO(node, p, m) for node in l] return [NodeDTO(node, p, m) for node in l]
@self.app.get(self.core.context + "/nodes/search") @self.app.get(self.core.context + "/nodes/search")
async def listOfFindLikeName(name=str): async def listOfFindLikeName(name=str, devices: List[str] = Query([])):
l = await self.dbService.listOfFindLikeName(name) l = await self.dbService.listOfFindLikeName(name, devices)
return [NodeShortDTO(node) for node in l] return [NodeShortDTO(node) for node in l]
@self.app.get(self.core.context + "/nodes/{num}") @self.app.get(self.core.context + "/nodes/{num}")
@self.core.authManager.authRequest() @self.core.authManager.authRequest()
async def oneNode(request: Request, num: int, p: bool = Query(False), m:bool = Query(False)): async def oneNode(request: Request,
c = await self.dbService.oneNode(num) num: int,
p: bool = Query(False),
m:bool = Query(False),
devices: List[str] = Query([])):
c = await self.dbService.oneNode(num, devices)
if c: if c:
return NodeDTO(c, p, m) return NodeDTO(c, p, m)
else: else:
@ -43,9 +53,13 @@ class WebExtension:
@self.app.get(self.core.context + "/nodes") @self.app.get(self.core.context + "/nodes")
@self.core.authManager.authRequest() @self.core.authManager.authRequest()
async def listOfSelectedNodes(request: Request, nums: List[int] = Query(None), p: bool = Query(False), m:bool = Query(False)): async def listOfSelectedNodes(request: Request,
nums: List[int] = Query(None),
p: bool = Query(False),
m:bool = Query(False),
devices: List[str] = Query([])):
if type(nums) != list: if type(nums) != list:
nums = [nums] nums = [nums]
l = await self.dbService.listOfSelectedNodes(nums) l = await self.dbService.listOfSelectedNodes(nums, devices)
return [NodeDTO(node, p, m) for node in l] return [NodeDTO(node, p, m) for node in l]

10
webExtensions/packetEndpoint.py

@ -24,8 +24,9 @@ class WebExtension:
nums: List[int] = Query([]), nums: List[int] = Query([]),
portnums: List[int] = Query([]), portnums: List[int] = Query([]),
packetsPerNode:bool = Query(False), packetsPerNode:bool = Query(False),
packetsSumNode:bool = Query(False)): packetsSumNode:bool = Query(False),
gl = await self.core.dbService.findPacketsAndGroupCount(after, before, nums, portnums, packetsPerNode, packetsSumNode) devices: List[str] = Query([])):
gl = await self.core.dbService.findPacketsAndGroupCount(after, before, nums, portnums, packetsPerNode, packetsSumNode, devices)
return gl return gl
@self.app.get(f"{self.core.context}/packet/signal") @self.app.get(f"{self.core.context}/packet/signal")
@ -33,6 +34,7 @@ class WebExtension:
async def findPacketsAndGroupCount(request: Request, async def findPacketsAndGroupCount(request: Request,
after: float = Query(-1), after: float = Query(-1),
before: float = Query(-1), before: float = Query(-1),
nums: List[int] = Query([])): nums: List[int] = Query([]),
gl = await self.core.dbService.findPacketsSignals(after, before, nums) devices: List[str] = Query([])):
gl = await self.core.dbService.findPacketsSignals(after, before, nums, devices)
return gl return gl
Loading…
Cancel
Save