From db65beae90630c02f67324b2b17f9204a12849cd Mon Sep 17 00:00:00 2001 From: Jason <81298350+Deutscher775@users.noreply.github.com> Date: Sun, 29 Sep 2024 22:09:26 +0200 Subject: [PATCH] add statistics --- src/api.py | 13 ++++-- src/astroidapi/errors.py | 38 ++++++++++++++++- src/astroidapi/sending_handler.py | 2 + src/astroidapi/statistics.py | 39 +++++++++++++++++ src/astroidapi/surrealdb_handler.py | 65 +++++++++++++++++++++++++++++ 5 files changed, 152 insertions(+), 5 deletions(-) create mode 100644 src/astroidapi/statistics.py diff --git a/src/api.py b/src/api.py index 9da374e..7fa4d85 100644 --- a/src/api.py +++ b/src/api.py @@ -1,9 +1,7 @@ -import asyncio import json import os import pathlib import traceback -import aiohttp import uvicorn import fastapi import Bot.config @@ -17,13 +15,13 @@ import astroidapi.health_check import astroidapi.read_handler import astroidapi.surrealdb_handler +import astroidapi.statistics import beta_users from fastapi.middleware.cors import CORSMiddleware import requests import sentry_sdk from PIL import Image from fastapi import HTTPException -import time import slowapi from slowapi.errors import RateLimitExceeded from slowapi import Limiter @@ -137,6 +135,12 @@ def root(): } return fastapi.responses.JSONResponse(status_code=200, content=home_data) + +@api.get("/statistics", description="Get the statistics.") +async def get_statistics(): + await astroidapi.surrealdb_handler.Statistics.update_messages(1) + return await astroidapi.statistics.get_statistics() + @api.get("/invite/{platform}", description="Get the invite link for the astroid bot.") def invite(platform: str, token: Annotated[str, fastapi.Query(max_length=85)] = None): if platform == "discord": @@ -705,6 +709,7 @@ async def get_channel_name(platform: str, id: str, token: Annotated[str, fastapi return fastapi.responses.JSONResponse(status_code=404, content={"message": "This channel does not exist."}) + logging.info("[CORE] API started.") -uvicorn.run(api, host="localhost", port=9921) +uvicorn.run(api, host="localhost", port=9921) \ No newline at end of file diff --git a/src/astroidapi/errors.py b/src/astroidapi/errors.py index 3d7d9a0..227060c 100644 --- a/src/astroidapi/errors.py +++ b/src/astroidapi/errors.py @@ -172,6 +172,37 @@ class CheckEligibilityError(Exception): def __init__(self, message): self.message = message super().__init__(self.message) + + class ProfileNotFoundError(Exception): + def __init__(self, message): + self.message = message + super().__init__(self.message) + + class ProfileCreationError(Exception): + def __init__(self, message): + self.message = message + super().__init__(self.message) + + class ProfileUpdateError(Exception): + def __init__(self, message): + self.message = message + super().__init__(self.message) + + class ProfileDeletionError(Exception): + def __init__(self, message): + self.message = message + super().__init__(self.message) + + class GetProfileError(Exception): + def __init__(self, message): + self.message = message + super().__init__(self.message) + + class GetStatisticsError(Exception): + def __init__(self, message): + self.message = message + super().__init__(self.message) + class ReadHandlerError: @@ -234,4 +265,9 @@ def __init__(self, message): super().__init__(self.message) - \ No newline at end of file + +class ProfileProcessorError: + class ProfileNotFoundError(Exception): + def __init__(self, message): + self.message = message + super().__init__(self.message) \ No newline at end of file diff --git a/src/astroidapi/sending_handler.py b/src/astroidapi/sending_handler.py index c2bf93b..e513eb5 100644 --- a/src/astroidapi/sending_handler.py +++ b/src/astroidapi/sending_handler.py @@ -8,6 +8,7 @@ import astroidapi.read_handler as read_handler import astroidapi.formatter as formatter import astroidapi.attachment_processor as attachment_processor +import astroidapi.statistics as statistics import os import traceback @@ -46,6 +47,7 @@ async def distribute(cls, endpoint, updated_json): if sender == "nerimity": await cls.send_from_nerimity(updated_json, endpoint, attachments) await attachment_processor.clear_temporary_attachments() + asyncio.create_task(statistics.update_statistics()) return True except Exception as e: traceback.print_exc() diff --git a/src/astroidapi/statistics.py b/src/astroidapi/statistics.py new file mode 100644 index 0000000..57aa0a7 --- /dev/null +++ b/src/astroidapi/statistics.py @@ -0,0 +1,39 @@ +import math +import astroidapi.surrealdb_handler as surrealdb_handler + +async def get_statistics(): + statistics = await surrealdb_handler.Statistics.getall() + total_messages = statistics["messages"]["total"] + def round_down_to_nearest(x, base): + return base * math.floor(x / base) + + if total_messages < 10: + total_messages_rounded = total_messages + elif total_messages < 50: + total_messages_rounded = round_down_to_nearest(total_messages, 10) + elif total_messages < 100: + total_messages_rounded = round_down_to_nearest(total_messages, 50) + elif total_messages < 500: + total_messages_rounded = round_down_to_nearest(total_messages, 100) + else: + total_messages_rounded = round_down_to_nearest(total_messages, 1000) + statistics["messages"]["total_rounded"] = total_messages_rounded + + total_monthly_messages = statistics["messages"]["month"] + if total_monthly_messages < 10: + total_monthly_messages_rounded = total_monthly_messages + elif total_monthly_messages < 50: + total_monthly_messages_rounded = round_down_to_nearest(total_monthly_messages, 10) + elif total_monthly_messages < 100: + total_monthly_messages_rounded = round_down_to_nearest(total_monthly_messages, 50) + elif total_monthly_messages < 500: + total_monthly_messages_rounded = round_down_to_nearest(total_monthly_messages, 100) + else: + total_monthly_messages_rounded = round_down_to_nearest(total_monthly_messages, 1000) + statistics["messages"]["month_rounded"] = total_monthly_messages_rounded + + + return statistics + +async def update_statistics(): + await surrealdb_handler.Statistics.update_messages(1) \ No newline at end of file diff --git a/src/astroidapi/surrealdb_handler.py b/src/astroidapi/surrealdb_handler.py index 4946861..59be32e 100644 --- a/src/astroidapi/surrealdb_handler.py +++ b/src/astroidapi/surrealdb_handler.py @@ -5,6 +5,9 @@ import astroidapi.errors as errors import traceback import pathlib +import random +import string +import datetime async def sync_local_files(folderpath: str, specific: bool = False): try: @@ -197,8 +200,10 @@ async def check_eligibility(cls, endpoint: int): await db.signin({"user": config.SDB_USER, "pass": config.SDB_PASS}) await db.use(config.SDB_NAMESPACE, config.SDB_DATABASE) elegible_endpoints = await db.select("attachments:eligible_endpoints") + print(elegible_endpoints) if endpoint in elegible_endpoints["endpoints"]: return True + return False except Exception as e: raise errors.SurrealDBHandler.CheckEligibilityError(e) @@ -270,3 +275,63 @@ async def for_nerimity(cls, endpoint: int, nerimity_id: str): except Exception as e: raise errors.SurrealDBHandler.CreateEndpointError(e) + + + + +class Statistics: + + @staticmethod + async def getall(): + try: + async with Surreal(config.SDB_URL) as db: + await db.signin({"user": config.SDB_USER, "pass": config.SDB_PASS}) + await db.use(config.SDB_NAMESPACE, config.SDB_DATABASE) + messages = await db.select("statistics:messages") + entpoints = len(await db.select("endpoints")) + + return { + "messages": messages, + "endpoints": entpoints + } + except Exception as e: + raise errors.SurrealDBHandler.GetStatisticsError(e) + + @staticmethod + async def get_messages(): + try: + async with Surreal(config.SDB_URL) as db: + await db.signin({"user": config.SDB_USER, "pass": config.SDB_PASS}) + await db.use(config.SDB_NAMESPACE, config.SDB_DATABASE) + return await db.select("statistics:messages") + except Exception as e: + raise errors.SurrealDBHandler.GetStatisticsError(e) + + @staticmethod + async def update_messages(increment: int, start_period: bool = False): + try: + async with Surreal(config.SDB_URL) as db: + await db.signin({"user": config.SDB_USER, "pass": config.SDB_PASS}) + await db.use(config.SDB_NAMESPACE, config.SDB_DATABASE) + current = datetime.datetime.fromtimestamp(datetime.datetime.now().timestamp()) + total = await db.select("statistics:messages") + total = total["total"] + await db.query(f"UPDATE statistics:messages SET total = {total + increment}") + if start_period: + await db.query(f"UPDATE statistics:messages SET periodStart = {datetime.datetime.now().timestamp()}") + await db.query(f"UPDATE statistics:messages SET month = 0") + period_start = await db.select("statistics:messages") + period_start = period_start["periodStart"] + print(datetime.datetime.fromtimestamp(period_start) + datetime.timedelta(weeks=4)) + if current >= datetime.datetime.fromtimestamp(period_start) + datetime.timedelta(weeks=4): + await db.query(f"UPDATE statistics:messages SET periodStart = {datetime.datetime.now().timestamp()}") + await db.query(f"UPDATE statistics:messages SET month = 0") + else: + moth = await db.select("statistics:messages") + moth = moth["month"] + await db.query(f"UPDATE statistics:messages SET month = {moth + increment}") + + return await db.select("statistics:messages") + except Exception as e: + traceback.print_exc() + raise errors.SurrealDBHandler.GetStatisticsError(e) \ No newline at end of file