neptune/core/lib/threshold.py

139 lines
3.7 KiB
Python
Raw Normal View History

2022-07-21 12:51:12 +00:00
import logging
from json import dumps
2022-07-26 21:15:30 +00:00
from operator import itemgetter
from typing import OrderedDict
2022-07-21 12:51:12 +00:00
import requests
from django.conf import settings
from requests.exceptions import JSONDecodeError
logger = logging.getLogger(__name__)
def escape(obj):
chars = ["[", "]", "^", "-", "*", "?"]
if isinstance(obj, str):
obj = obj.replace("\\", "\\\\")
for i in chars:
obj = obj.replace(i, "\\" + i)
elif isinstance(obj, list):
for i in obj:
i = escape(i)
elif isinstance(obj, dict):
for key in obj:
obj[key] = escape(obj[key])
return obj
2022-07-21 12:51:43 +00:00
def sort_data(data):
2022-07-29 21:22:22 +00:00
for item in data.keys():
2022-07-21 12:51:43 +00:00
if isinstance(data[item], list):
cont = False
2022-07-29 21:22:22 +00:00
for v in data[item]:
if isinstance(v, list):
cont = True
if isinstance(v, dict):
cont = True
if cont:
continue
2022-07-21 12:51:43 +00:00
data[item].sort()
2022-07-26 21:15:30 +00:00
elif isinstance(data[item], dict):
2022-07-29 21:22:22 +00:00
# Don't sort nested stuff
cont = False
for k, v in data[item].items():
if isinstance(v, list):
cont = True
if isinstance(v, dict):
cont = True
if cont:
continue
2022-07-26 21:15:30 +00:00
sorted_item = sorted(data[item].items(), key=itemgetter(1), reverse=True)
data[item] = OrderedDict({k: v for k, v in sorted_item})
2022-07-21 12:51:43 +00:00
2022-08-01 18:06:56 +00:00
def threshold_request(url, data, method="POST", esc=False):
2022-07-21 12:51:12 +00:00
headers = {
"ApiKey": settings.THRESHOLD_API_KEY,
"Token": settings.THRESHOLD_API_TOKEN,
}
2022-08-01 18:06:56 +00:00
if esc:
for key in data:
data[key] = escape(data[key])
2022-07-27 19:53:41 +00:00
if method == "POST":
method = requests.post
elif method == "GET":
method = requests.get
elif method == "DELETE":
method = requests.delete
elif method == "PUT":
method = requests.put
else:
logger.error("Invalid method specified")
method = requests.get
r = method(
2022-07-21 12:51:12 +00:00
f"{settings.THRESHOLD_ENDPOINT}/{url}/", data=dumps(data), headers=headers
)
if not r.headers.get("Counter") == settings.THRESHOLD_API_COUNTER:
logger.error(
(
f"Threshold API counter mismatch: "
f"{r.headers.get('Counter')} != "
f"{settings.THRESHOLD_API_COUNTER}"
)
)
return False
try:
response = r.json()
sort_data(response)
2022-07-21 12:51:12 +00:00
except JSONDecodeError:
logging.error(f"Invalid JSON response: {r.text}")
return False
2022-07-21 12:51:12 +00:00
return response
def get_chans(net, query):
url = "chans"
payload = {"net": net, "query": query}
2022-08-01 18:06:56 +00:00
channels = threshold_request(url, payload, esc=True)
2022-07-21 12:51:12 +00:00
if not channels:
return []
return channels["chans"]
def get_users(net, query):
url = "users"
payload = {"net": net, "query": query}
2022-08-01 18:06:56 +00:00
users = threshold_request(url, payload, esc=True)
2022-07-21 12:51:12 +00:00
if not users:
return []
return users["users"]
def annotate_online(net, query):
url = "online"
payload = {"net": net, "query": query}
2022-08-01 18:06:56 +00:00
online_info = threshold_request(url, payload, esc=True)
2022-07-21 12:51:12 +00:00
if not online_info:
return {}
return online_info
def annotate_num_users(net, query):
url = "num_users"
payload = {"net": net, "query": query}
2022-08-01 18:06:56 +00:00
user_num_map = threshold_request(url, payload, esc=True)
if not user_num_map:
return {}
return user_num_map
def annotate_num_chans(net, query):
url = "num_chans"
payload = {"net": net, "query": query}
2022-08-01 18:06:56 +00:00
chan_num_map = threshold_request(url, payload, esc=True)
if not chan_num_map:
return {}
return chan_num_map