diff --git a/app/classes/models/users.py b/app/classes/models/users.py index b0612017..ccd8f1b0 100644 --- a/app/classes/models/users.py +++ b/app/classes/models/users.py @@ -45,6 +45,7 @@ class Users(BaseModel): manager = IntegerField(default=None, null=True) pfp = CharField(default="/static/assets/images/faces-clipart/pic-3.png") theme = CharField(default="default") + cleared_notifs = CharField(default="default") class Meta: table_name = "users" @@ -171,6 +172,7 @@ class HelperUsers: "roles": [], "servers": [], "support_logs": "", + "cleared_notifs": "", } user = model_to_dict(Users.get(Users.user_id == user_id)) diff --git a/app/classes/shared/helpers.py b/app/classes/shared/helpers.py index 489115ae..59c1ae3a 100644 --- a/app/classes/shared/helpers.py +++ b/app/classes/shared/helpers.py @@ -581,12 +581,16 @@ class Helpers: @staticmethod def get_announcements(): - data = ( - '[{"id":"1","date":"Unknown",' - '"title":"Error getting Announcements",' - '"desc":"Error getting Announcements","link":""}]' - ) - + data = [] + data = [ + { + "id": "4db1a43b-d451-4abc-bb10-5a45676d95f7", + "date": "Unknown", + "title": "Error getting Announcements", + "desc": "Error getting Announcements", + "link": "", + } + ] try: response = requests.get("https://craftycontrol.com/notify.json", timeout=2) data = json.loads(response.content) diff --git a/app/classes/web/routes/api/api_handlers.py b/app/classes/web/routes/api/api_handlers.py index 29ee02c5..c3558a65 100644 --- a/app/classes/web/routes/api/api_handlers.py +++ b/app/classes/web/routes/api/api_handlers.py @@ -40,6 +40,7 @@ from app.classes.web.routes.api.users.user.permissions import ( ) from app.classes.web.routes.api.users.user.pfp import ApiUsersUserPfpHandler from app.classes.web.routes.api.users.user.public import ApiUsersUserPublicHandler +from app.classes.web.routes.api.crafty.announcements.index import ApiAnnounceIndexHandler def api_handlers(handler_args): @@ -55,6 +56,11 @@ def api_handlers(handler_args): ApiAuthInvalidateTokensHandler, handler_args, ), + ( + r"/api/v2/crafty/announcements/?", + ApiAnnounceIndexHandler, + handler_args, + ), # User routes ( r"/api/v2/users/?", diff --git a/app/classes/web/routes/api/crafty/announcements/index.py b/app/classes/web/routes/api/crafty/announcements/index.py new file mode 100644 index 00000000..a7012466 --- /dev/null +++ b/app/classes/web/routes/api/crafty/announcements/index.py @@ -0,0 +1,106 @@ +import logging +import json +from jsonschema import ValidationError, validate +from app.classes.web.base_api_handler import BaseApiHandler + +logger = logging.getLogger(__name__) + +notif_schema = { + "type": "object", + "properties": { + "id": {"type": "string"}, + }, + "additionalProperties": False, + "minProperties": 1, +} + + +class ApiAnnounceIndexHandler(BaseApiHandler): + def get(self): + auth_data = self.authenticate_user() + if not auth_data: + return + ( + _, + _exec_user_crafty_permissions, + _, + _, + _user, + ) = auth_data + + data = self.helper.get_announcements() + cleared = str( + self.controller.users.get_user_by_id(auth_data[4]["user_id"])[ + "cleared_notifs" + ] + ).split(",") + res = [d.get("id", None) for d in data] + # remove notifs that are no longer in Crafty. + for item in cleared[:]: + if item not in res: + cleared.remove(item) + if len(cleared) > 0: + for item in data[:]: + if item["id"] in cleared: + data.remove(item) + + self.finish_json( + 200, + { + "status": "ok", + "data": data, + }, + ) + + def post(self): + auth_data = self.authenticate_user() + if not auth_data: + return + ( + _, + _exec_user_crafty_permissions, + _, + _, + _user, + ) = auth_data + print(self.request) + try: + data = json.loads(self.request.body) + print(data) + except json.decoder.JSONDecodeError as e: + return self.finish_json( + 400, {"status": "error", "error": "INVALID_JSON", "error_data": str(e)} + ) + + try: + validate(data, notif_schema) + except ValidationError as e: + return self.finish_json( + 400, + { + "status": "error", + "error": "INVALID_JSON_SCHEMA", + "error_data": str(e), + }, + ) + announcements = self.helper.get_announcements() + res = [d.get("id", None) for d in announcements] + cleared_notifs = str( + self.controller.users.get_user_by_id(auth_data[4]["user_id"])[ + "cleared_notifs" + ] + ).split(",") + # remove notifs that are no longer in Crafty. + for item in cleared_notifs[:]: + if item not in res: + cleared_notifs.remove(item) + cleared_notifs.append(data["id"]) + updata = {"cleared_notifs": ",".join(cleared_notifs)} + self.controller.users.update_user(auth_data[4]["user_id"], updata) + self.finish_json( + 200, + { + "status": "ok", + "data": {}, + }, + ) diff --git a/app/frontend/templates/notify.html b/app/frontend/templates/notify.html index 9d41d17d..1600e0f5 100644 --- a/app/frontend/templates/notify.html +++ b/app/frontend/templates/notify.html @@ -1,27 +1,32 @@ + \ No newline at end of file diff --git a/app/migrations/20230901_user_notif.py b/app/migrations/20230901_user_notif.py new file mode 100644 index 00000000..eaefc159 --- /dev/null +++ b/app/migrations/20230901_user_notif.py @@ -0,0 +1,16 @@ +# Generated by database migrator +import peewee + + +def migrate(migrator, database, **kwargs): + migrator.add_columns("users", cleared_notifs=peewee.CharField(default="")) + """ + Write your migrations here. + """ + + +def rollback(migrator, database, **kwargs): + migrator.drop_columns("users", ["cleared_notifs"]) + """ + Write your rollback migrations here. + """