diff --git a/.gitignore b/.gitignore index ef828e6..cb72c18 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ .idea .git *.log -*_servers* .github LICENSE tokens.json @@ -9,19 +8,17 @@ tokens.json beta Copy of endpoints beta_users.py -tokens.json TMP __pycache__ endpoints* -tokens* -src/tokens.json -src/Bot/config.py src/_astroidapi.log /website /web website.zip -src/Bot/config.py src/astroidapi.zip src/astroidapi/beta_config.py src/Bot/config.py - +src/Bot/nerimity_servers/1528027692992208896.json +src/tokens.json +assets/517057624072519680.png +src/astroidapi/test.py diff --git a/src/.tokens.json b/src/.tokens.json index d3f5a12..e69de29 100644 --- a/src/.tokens.json +++ b/src/.tokens.json @@ -1 +0,0 @@ - diff --git a/src/Bot/.config.py b/src/Bot/.config.py index e4eb308..c5ffb90 100644 --- a/src/Bot/.config.py +++ b/src/Bot/.config.py @@ -9,4 +9,4 @@ SDB_USER = "" SDB_PASS = "" SDB_NAMESPACE = "" -SDB_DATABASE = "" +SDB_DATABASE = "" \ No newline at end of file diff --git a/src/api.py b/src/api.py index 8fad2bd..aefa70b 100644 --- a/src/api.py +++ b/src/api.py @@ -64,10 +64,6 @@ docs_url=None ) - - - - api.add_middleware( CORSMiddleware, allow_origins=["*"], @@ -490,6 +486,23 @@ async def endpoint_healthcheck(endpoint: int, token: str): "details": "getendpointerror"}) +@api.post("/healthcheck/{endpoint}/repair", description="Repair the endpoint.") +async def repair_endpoint(endpoint: int, token: str): + suspend_status = await astroidapi.suspension_handler.Endpoint.is_suspended(endpoint) + if suspend_status: + return fastapi.responses.JSONResponse(status_code=403, content={"message": "This endpoint is suspended."}) + + if token == Bot.config.MASTER_TOKEN: + try: + summary = await astroidapi.health_check.HealthCheck.EndpointCheck.repair_structure(endpoint) + return fastapi.responses.JSONResponse(status_code=200, content={"message": "Repaired.", "summary": summary}) + except Exception as e: + logging.exception(traceback.print_exc()) + return fastapi.responses.JSONResponse(status_code=500, content={"message": f"An error occurred: {e}"}) + else: + return fastapi.responses.JSONResponse(status_code=401, content={"message": "The provided token is invalid."}) + + @api.post("/create", description="Create an endpoint.", response_description="Endpoints data.") async def create_endpoint(endpoint: int): diff --git a/src/astroidapi/health_check.py b/src/astroidapi/health_check.py index d3f4696..b4fabeb 100644 --- a/src/astroidapi/health_check.py +++ b/src/astroidapi/health_check.py @@ -4,9 +4,75 @@ import json +writes = { + "config": { + "self-user": "config.`self-user`", + "type_webhooks": "config.webhooks", + "webhooks": { + "discord": "config.webhooks.discord", + "guilded": "config.webhooks.guilded", + "revolt": "config.webhooks.revolt", + "nerimity": "config.webhooks.nerimity" + }, + "type_channels": "config.channels", + "channels": { + "discord": "config.channels.discord", + "guilded": "config.channels.guilded", + "revolt": "config.channels.revolt", + "nerimity": "config.channels.nerimity" + }, + "type_logs": "config.logs", + "logs": { + "discord": "config.logs.discord", + "guilded": "config.logs.guilded", + "revolt": "config.logs.revolt", + "nerimity": "config.logs.nerimity" + }, + "blacklist": "config.blacklist", + "allowed-ids": "config.`allowed-ids`", + "isbeta": "config.isbeta`" + }, + "meta": { + "sender-channel": "meta.`sender-channel`", + "trigger": "meta.trigger", + "sender": "meta.sender", + "type_read": "meta.read", + "read": { + "discord": "meta.read.discord", + "guilded": "meta.read.guilded", + "revolt": "meta.read.revolt", + "nerimity": "meta.read.nerimity" + }, + "type_message": "meta.message", + "message": { + "type_author": "meta.message.author", + "author": { + "name": "meta.message.author.name", + "avatar": "meta.message.author.avatar", + "id": "meta.message.author.id" + }, + "content": "meta.message.content", + "attachments": "meta.message.attachments" + } + } +} + + + class HealthCheck: - class EndpointCheck: + @staticmethod + def convert_keys_to_dotted(json_data, parent_key=""): + dotted_dict = {} + for key, value in json_data.items(): + if isinstance(value, dict): + dotted_dict.update(HealthCheck.convert_keys_to_dotted(value, f"{parent_key}`{key}`.")) + else: + dotted_dict[f"{parent_key}`{key}`"] = value + return dotted_dict + + + class EndpointCheck: @classmethod async def check(cls, endpoint): healthy_endpoint_data = { @@ -67,6 +133,305 @@ async def check(cls, endpoint): return True except IndexError as e: raise errors.HealtCheckError.EndpointCheckError(e) + + @classmethod + async def repair_structure(cls, endpoint): + healthy_endpoint_data = { + "config": { + "self-user": False, + "type_webhooks": {}, + "webhooks": { + "discord": [], + "guilded": [], + "revolt": [], + "nerimity": [] + }, + "type_channels": {}, + "channels": { + "discord": [], + "guilded": [], + "revolt": [], + "nerimity": [] + }, + "type_logs": {}, + "logs": { + "discord": "NULL", + "guilded": "NULL", + "revolt": "NULL", + "nerimity": "NULL" + }, + "blacklist": [], + "allowed-ids": [], + "isbeta": False + }, + "meta": { + "sender-channel": "NULL", + "trigger": False, + "sender": "NULL", + "type_read": {}, + "read": { + "discord": False, + "guilded": False, + "revolt": False, + "nerimity": False + }, + "type_message": {}, + "message": { + "type_author": {}, + "author": { + "name": "NULL", + "avatar": "NULL", + "id": "NULL" + }, + "content": "NULL", + "attachments": [] + } + } + } + try: + endpoint_data = await surrealdb_handler.get_endpoint(endpoint) + summary = [] + try: + self_user = endpoint_data["config"]["self-user"] + summary.append("✔ Self user found") + except KeyError: + await surrealdb_handler.write_to_structure(endpoint, writes["config"]["self-user"], healthy_endpoint_data["config"]["self-user"]) + summary.append("✘ Self user not found. Adding...") + await asyncio.sleep(0.1) + try: + webhooks = endpoint_data["config"]["webhooks"] + summary.append("✔ Webhooks found") + except KeyError: + await surrealdb_handler.write_to_structure(endpoint, writes["config"]["type_webhooks"], healthy_endpoint_data["config"]["type_webhooks"]) + summary.append("✘ Webhooks not found. Adding...") + await asyncio.sleep(0.1) + try: + webhooks_discord = endpoint_data["config"]["webhooks"]["discord"] + summary.append("✔ Webhooks - Discord found") + except KeyError: + await surrealdb_handler.write_to_structure(endpoint, writes["config"]["webhooks"]["discord"], healthy_endpoint_data["config"]["webhooks"]["discord"]) + summary.append("✘ Webhooks - Discord not found. Adding...") + await asyncio.sleep(0.1) + try: + webhooks_guilded = endpoint_data["config"]["webhooks"]["guilded"] + summary.append("✔ Webhooks - Guilded found") + except KeyError: + await surrealdb_handler.write_to_structure(endpoint, writes["config"]["webhooks"]["guilded"], healthy_endpoint_data["config"]["webhooks"]["guilded"]) + summary.append("✘ Webhooks - Guilded not found. Adding...") + await asyncio.sleep(0.1) + try: + webhooks_revolt = endpoint_data["config"]["webhooks"]["revolt"] + summary.append("✔ Webhooks - Revolt found") + except KeyError: + await surrealdb_handler.write_to_structure(endpoint, writes["config"]["webhooks"]["revolt"], healthy_endpoint_data["config"]["webhooks"]["revolt"]) + summary.append("✘ Webhooks - Revolt not found. Adding...") + await asyncio.sleep(0.1) + try: + webhooks_nerimity = endpoint_data["config"]["webhooks"]["nerimity"] + summary.append("✔ Webhooks - Nerimity found") + except KeyError: + await surrealdb_handler.write_to_structure(endpoint, writes["config"]["webhooks"]["nerimity"], healthy_endpoint_data["config"]["webhooks"]["nerimity"]) + summary.append("✘ Webhooks - Nerimity not found. Adding...") + await asyncio.sleep(0.1) + try: + channels = endpoint_data["config"]["channels"] + summary.append("✔ Channels found") + except KeyError: + await surrealdb_handler.write_to_structure(endpoint, writes["config"]["type_channels"], healthy_endpoint_data["config"]["type_channels"]) + summary.append("✘ Channels not found. Adding...") + await asyncio.sleep(0.1) + try: + channels_discord = endpoint_data["config"]["channels"]["discord"] + summary.append("✔ Channels - Discord found") + except KeyError: + await surrealdb_handler.write_to_structure(endpoint, writes["config"]["channels"]["discord"], healthy_endpoint_data["config"]["channels"]["discord"]) + summary.append("✘ Channels - Discord not found. Adding...") + await asyncio.sleep(0.1) + try: + channels_guilded = endpoint_data["config"]["channels"]["guilded"] + summary.append("✔ Channels - Guilded found") + except KeyError: + await surrealdb_handler.write_to_structure(endpoint, writes["config"]["channels"]["guilded"], healthy_endpoint_data["config"]["channels"]["guilded"]) + summary.append("✘ Channels - Guilded not found. Adding...") + await asyncio.sleep(0.1) + try: + channels_revolt = endpoint_data["config"]["channels"]["revolt"] + summary.append("✔ Channels - Revolt found") + except KeyError: + await surrealdb_handler.write_to_structure(endpoint, writes["config"]["channels"]["revolt"], healthy_endpoint_data["config"]["channels"]["revolt"]) + summary.append("✘ Channels - Revolt not found. Adding...") + await asyncio.sleep(0.1) + try: + channels_nerimity = endpoint_data["config"]["channels"]["nerimity"] + summary.append("✔ Channels - Nerimity found") + except KeyError: + await surrealdb_handler.write_to_structure(endpoint, writes["config"]["channels"]["nerimity"], healthy_endpoint_data["config"]["channels"]["nerimity"]) + summary.append("✘ Channels - Nerimity not found. Adding...") + await asyncio.sleep(0.1) + try: + logs = endpoint_data["config"]["logs"] + summary.append("✔ Logs found") + except KeyError: + await surrealdb_handler.write_to_structure(endpoint, writes["config"]["type_logs"], healthy_endpoint_data["config"]["type_logs"]) + summary.append("✘ Logs not found. Adding...") + await asyncio.sleep(0.1) + try: + logs_discord = endpoint_data["config"]["logs"]["discord"] + summary.append("✔ Logs - Discord found") + except KeyError: + await surrealdb_handler.write_to_structure(endpoint, writes["config"]["logs"]["discord"], healthy_endpoint_data["config"]["logs"]["discord"]) + summary.append("✘ Logs - Discord not found. Adding...") + await asyncio.sleep(0.1) + try: + logs_guilded = endpoint_data["config"]["logs"]["guilded"] + summary.append("✔ Logs - Guilded found") + except KeyError: + await surrealdb_handler.write_to_structure(endpoint, writes["config"]["logs"]["guilded"], healthy_endpoint_data["config"]["logs"]["guilded"]) + summary.append("✘ Logs - Guilded not found. Adding...") + await asyncio.sleep(0.1) + try: + logs_revolt = endpoint_data["config"]["logs"]["revolt"] + summary.append("✔ Logs - Revolt found") + except KeyError: + await surrealdb_handler.write_to_structure(endpoint, writes["config"]["logs"]["revolt"], healthy_endpoint_data["config"]["logs"]["revolt"]) + summary.append("✘ Logs - Revolt not found. Adding...") + await asyncio.sleep(0.1) + try: + logs_nerimity = endpoint_data["config"]["logs"]["nerimity"] + summary.append("✔ Logs - Nerimity found") + except KeyError: + await surrealdb_handler.write_to_structure(endpoint, writes["config"]["logs"]["nerimity"], healthy_endpoint_data["config"]["logs"]["nerimity"]) + summary.append("✘ Logs - Nerimity not found. Adding...") + await asyncio.sleep(0.1) + try: + blacklist = endpoint_data["config"]["blacklist"] + summary.append("✔ Blacklist found") + except KeyError: + await surrealdb_handler.write_to_structure(endpoint, writes["config"]["blacklist"], healthy_endpoint_data["config"]["blacklist"]) + summary.append("✘ Blacklist not found. Adding...") + await asyncio.sleep(0.1) + try: + allowed_ids = endpoint_data["config"]["allowed-ids"] + summary.append("✔ Allowed IDs found") + except KeyError: + await surrealdb_handler.write_to_structure(endpoint, writes["config"]["allowed-ids"], healthy_endpoint_data["config"]["allowed-ids"]) + summary.append("✘ Allowed IDs not found. Adding...") + await asyncio.sleep(0.1) + try: + isbeta = endpoint_data["config"]["isbeta"] + summary.append("✔ IsBeta found") + except KeyError: + await surrealdb_handler.write_to_structure(endpoint, writes["config"]["isbeta"], healthy_endpoint_data["config"]["isbeta"]) + summary.append("✘ IsBeta not found. Adding...") + await asyncio.sleep(0.1) + try: + sender_channel = endpoint_data["meta"]["sender-channel"] + summary.append("✔ Meta - Sender Channel found") + except KeyError: + await surrealdb_handler.write_to_structure(endpoint, writes["meta"]["sender-channel"], healthy_endpoint_data["meta"]["sender-channel"]) + summary.append("✘ Meta - Sender Channel not found. Adding...") + await asyncio.sleep(0.1) + try: + trigger = endpoint_data["meta"]["trigger"] + summary.append("✔ Meta - Trigger found") + except KeyError: + await surrealdb_handler.write_to_structure(endpoint, writes["meta"]["trigger"], healthy_endpoint_data["meta"]["trigger"]) + summary.append("✘ Meta - Trigger not found. Adding...") + await asyncio.sleep(0.1) + try: + sender = endpoint_data["meta"]["sender"] + summary.append("✔ Meta - Sender found") + except KeyError: + await surrealdb_handler.write_to_structure(endpoint, writes["meta"]["sender"], healthy_endpoint_data["meta"]["sender"]) + summary.append("✘ Meta - Sender not found. Adding...") + await asyncio.sleep(0.1) + try: + read = endpoint_data["meta"]["read"] + summary.append("✔ Meta - Read found") + except KeyError: + await surrealdb_handler.write_to_structure(endpoint, writes["meta"]["type_read"], healthy_endpoint_data["meta"]["type_read"]) + summary.append("✘ Meta - Read not found. Adding...") + await asyncio.sleep(0.1) + try: + read_discord = endpoint_data["meta"]["read"]["discord"] + summary.append("✔ Meta - Read - Discord found") + except KeyError: + await surrealdb_handler.write_to_structure(endpoint, writes["meta"]["read"]["discord"], healthy_endpoint_data["meta"]["read"]["discord"]) + summary.append("✘ Meta - Read - Discord not found. Adding...") + await asyncio.sleep(0.1) + try: + read_guilded = endpoint_data["meta"]["read"]["guilded"] + summary.append("✔ Meta - Read - Guilded found") + except KeyError: + await surrealdb_handler.write_to_structure(endpoint, writes["meta"]["read"]["guilded"], healthy_endpoint_data["meta"]["read"]["guilded"]) + summary.append("✘ Meta - Read - Guilded not found. Adding...") + await asyncio.sleep(0.1) + try: + read_revolt = endpoint_data["meta"]["read"]["revolt"] + summary.append("✔ Meta - Read - Revolt found") + except KeyError: + await surrealdb_handler.write_to_structure(endpoint, writes["meta"]["read"]["revolt"], healthy_endpoint_data["meta"]["read"]["revolt"]) + summary.append("✘ Meta - Read - Revolt not found. Adding...") + await asyncio.sleep(0.1) + try: + read_nerimity = endpoint_data["meta"]["read"]["nerimity"] + summary.append("✔ Meta - Read - Nerimity found") + except KeyError: + await surrealdb_handler.write_to_structure(endpoint, writes["meta"]["read"]["nerimity"], healthy_endpoint_data["meta"]["read"]["nerimity"]) + summary.append("✘ Meta - Read - Nerimity not found. Adding...") + await asyncio.sleep(0.1) + try: + message = endpoint_data["meta"]["message"] + summary.append("✔ Meta - Message found") + except KeyError: + await surrealdb_handler.write_to_structure(endpoint, writes["meta"]["type_message"], healthy_endpoint_data["meta"]["type_message"]) + summary.append("✘ Meta - Message not found. Adding...") + await asyncio.sleep(0.1) + try: + message_author = endpoint_data["meta"]["message"]["author"] + summary.append("✔ Meta - Message - Author found") + except KeyError: + await surrealdb_handler.write_to_structure(endpoint, writes["meta"]["message"]["type_author"], healthy_endpoint_data["meta"]["message"]["type_author"]) + summary.append("✘ Meta - Message - Author not found. Adding...") + await asyncio.sleep(0.1) + try: + message_author_name = endpoint_data["meta"]["message"]["author"]["name"] + summary.append("✔ Meta - Message - Author - Name found") + except KeyError: + await surrealdb_handler.write_to_structure(endpoint, writes["meta"]["message"]["author"]["name"], healthy_endpoint_data["meta"]["message"]["author"]["name"]) + summary.append("✘ Meta - Message - Author - Name not found. Adding...") + await asyncio.sleep(0.1) + try: + message_author_avatar = endpoint_data["meta"]["message"]["author"]["avatar"] + summary.append("✔ Meta - Message - Author - Avatar found") + except KeyError: + await surrealdb_handler.write_to_structure(endpoint, writes["meta"]["message"]["author"]["avatar"], healthy_endpoint_data["meta"]["message"]["author"]["avatar"]) + summary.append("✘ Meta - Message - Author - Avatar not found. Adding...") + await asyncio.sleep(0.1) + try: + message_author_id = endpoint_data["meta"]["message"]["author"]["id"] + summary.append("✔ Meta - Message - Author - ID found") + except KeyError: + await surrealdb_handler.write_to_structure(endpoint, writes["meta"]["message"]["author"]["id"], healthy_endpoint_data["meta"]["message"]["author"]["id"]) + summary.append("✘ Meta - Message - Author - ID not found. Adding...") + await asyncio.sleep(0.1) + try: + message_content = endpoint_data["meta"]["message"]["content"] + summary.append("✔ Meta - Message - Content found") + except KeyError: + await surrealdb_handler.write_to_structure(endpoint, writes["meta"]["message"]["content"], healthy_endpoint_data["meta"]["message"]["content"]) + summary.append("✘ Meta - Message - Content not found. Adding...") + await asyncio.sleep(0.1) + try: + message_attachments = endpoint_data["meta"]["message"]["attachments"] + summary.append("✔ Meta - Message - Attachments found") + except KeyError: + await surrealdb_handler.write_to_structure(endpoint, writes["meta"]["message"]["attachments"], healthy_endpoint_data["meta"]["message"]["attachments"]) + print("Endpoint structure repaired") + print(summary) + return summary + except IndexError as e: + raise errors.HealtCheckError.EndpointCheckError(e) -asyncio.run(HealthCheck.EndpointCheck.check(1045437427965231284)) \ No newline at end of file +# asyncio.run(HealthCheck.EndpointCheck.repair_structure(1)) \ No newline at end of file diff --git a/src/astroidapi/surrealdb_handler.py b/src/astroidapi/surrealdb_handler.py index 88399c0..e490009 100644 --- a/src/astroidapi/surrealdb_handler.py +++ b/src/astroidapi/surrealdb_handler.py @@ -146,6 +146,19 @@ async def get_all_endpoints(): raise errors.SurrealDBHandler.GetEndpointError(e) +async def write_to_structure(endpoint, key, value): + print(f"Writing {key} to {endpoint}") + 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) + print(key, value) + await db.query(f"UPDATE endpoints:`{endpoint}` SET {key} = {value}") + return await db.query(f"SELECT * FROM endpoints:`{endpoint}`") + except Exception as e: + raise errors.SurrealDBHandler.UpdateEndpointError(e) + + class AttachmentProcessor: @classmethod diff --git a/src/astroidapi/test.py b/src/astroidapi/test.py new file mode 100644 index 0000000..08cae8f --- /dev/null +++ b/src/astroidapi/test.py @@ -0,0 +1,11 @@ +def convert_keys_to_dotted(json_data, parent_key=""): + dotted_dict = {} + for key, value in json_data.items(): + if isinstance(value, dict): + dotted_dict.update(convert_keys_to_dotted(value, f"{parent_key}{key}.")) + else: + dotted_dict[f"{parent_key}{key}"] = value + return dotted_dict + + +print(convert_keys_to_dotted({"a": {"b": {"c": 1}}})) \ No newline at end of file