From 5d797ee5440e20140967dc2a3f566354c2a78bfd Mon Sep 17 00:00:00 2001 From: wuttinanhi Date: Mon, 31 Oct 2022 18:31:01 +0000 Subject: [PATCH] update chat socket handler --- chat/handler.py | 48 +++++++++-- pagination/pagination.py | 34 +++++++- static/chat.html | 170 +++++++++++++++++++++++++++++++++++++++ static/socket-io.html | 147 --------------------------------- util/validate_request.py | 13 ++- 5 files changed, 253 insertions(+), 159 deletions(-) create mode 100644 static/chat.html delete mode 100644 static/socket-io.html diff --git a/chat/handler.py b/chat/handler.py index adae164..3df1977 100644 --- a/chat/handler.py +++ b/chat/handler.py @@ -1,14 +1,19 @@ """ chat socket handler """ + +from typing import Any, Dict + from auth.service import AuthService from flask import request from flask_socketio import Namespace, emit +from pagination.pagination import int_to_sort from user.model import User from user.service import UserService +from util.validate_request import validate_object from werkzeug.exceptions import NotFound, Unauthorized -from chat.service import ChatService +from chat.service import ChatHistoryPaginationOptions, ChatService class ChatMapper(Namespace): @@ -75,16 +80,47 @@ def on_login(self, data): ChatHandler.register(user, sid) return user.json() + # retrieve chat history + # request data json: + # { + # "jwt_token": "USER-JWT-TOKEN", + # "to_user": 1, + # "page": 1, + # "limit": 20, + # "sort": 1, + # "order_by": "send_date", + # "search": null, + # } def on_chat_list(self, data): user = ChatHandler.auth_user(data) - to_user_id = data["to_user"] - from_user = UserService.find_by_id(user.id) - to_user = UserService.find_by_id(to_user_id) + opts_dict: Dict[Any, Any] = {} + opts_dict["page"] = int(data["page"]) + opts_dict["limit"] = int(data["limit"]) + opts_dict["sort"] = int(data["sort"]) + opts_dict["order_by"] = data["order_by"] + opts_dict["from_user_id"] = int(user.id) + opts_dict["to_user_id"] = int(data["to_user"]) + if hasattr(data, "search"): + opts_dict["search"] = data["search"] + + vobj = validate_object(ChatHistoryPaginationOptions, opts_dict) + + opts = ChatHistoryPaginationOptions() + opts.page = int(vobj.page) + opts.limit = int(vobj.limit) + opts.sort = int_to_sort(int(vobj.sort)) + opts.order_by = vobj.order_by + opts.from_user_id = int(vobj.from_user_id) + opts.to_user_id = int(vobj.to_user_id) + if hasattr(vobj, "search"): + opts.search = vobj.search + else: + opts.search = "" + + chat_history = ChatService.list_chat_history(opts) response = [] - chat_history = ChatService.list_chat_history(from_user, to_user) - for chat in chat_history: response.append(chat.json()) diff --git a/pagination/pagination.py b/pagination/pagination.py index 51b7049..2a6a0c9 100644 --- a/pagination/pagination.py +++ b/pagination/pagination.py @@ -31,6 +31,14 @@ class PaginationOptions(Schema): ) +def int_to_sort(i: int): + if i == 0: + return PaginationSortOptions.ASC + if i == 1: + return PaginationSortOptions.DESC + raise BadRequest(f"Invalid pagination sort integer: {i}") + + def create_order_by(model, key: str, sort: PaginationSortOptions): if hasattr(model, key): result = model.__dict__.get(key) @@ -40,9 +48,7 @@ def create_order_by(model, key: str, sort: PaginationSortOptions): raise BadRequest(f"Invalid order by key!: {key}") -def create_pagination_options_from_request(request: Request): - data = validate_request(PaginationOptions, request, "GET") - +def create_pagination_options_from_schema(data): options = PaginationOptions() options.page = int(data.page) options.limit = int(data.limit) @@ -60,6 +66,28 @@ def create_pagination_options_from_request(request: Request): return options +def create_pagination_options_from_dict(data): + options = PaginationOptions() + options.page = int(data["page"]) + options.limit = int(data["limit"]) + options.order_by = data["order_by"] + + if hasattr(data, "search"): + options.search = data["search"] + else: + options.search = "" + + if int(data["sort"]) == 1: + options.sort = PaginationSortOptions.DESC + else: + options.sort = PaginationSortOptions.ASC + + return options + +def create_pagination_options_from_request(request: Request): + data = validate_request(PaginationOptions, request, "GET") + options = create_pagination_options_from_schema(data) + return options def create_pagination_options( page=1, limit=10, sort=PaginationSortOptions.ASC, order_by="id" diff --git a/static/chat.html b/static/chat.html new file mode 100644 index 0000000..bd9b871 --- /dev/null +++ b/static/chat.html @@ -0,0 +1,170 @@ + + + + + + + + Socket-IO test + + + +

Chat Test:

+
+
+ + +

+ + +

+ +
+
+
+
+
+

+
+ + +
+
+
+ + + + + + + + diff --git a/static/socket-io.html b/static/socket-io.html deleted file mode 100644 index 50fd3ec..0000000 --- a/static/socket-io.html +++ /dev/null @@ -1,147 +0,0 @@ - - - - - - - Socket-IO test - - -

Chat Test:

- - -

- - -

- -
-
-
-

- - - - - - - - - diff --git a/util/validate_request.py b/util/validate_request.py index 731e0ee..b56e0f3 100644 --- a/util/validate_request.py +++ b/util/validate_request.py @@ -7,12 +7,19 @@ from typing import Any, Dict, TypeVar from flask import Request -from marshmallow import ValidationError +from marshmallow import Schema, ValidationError T = TypeVar("T") -def validate_object(schema: T, obj: Any) -> T: - pass + +def validate_object(schema: T, dict: Any) -> T: + template: Schema = schema() + err = template.validate(dict) + if err: + raise ValidationError(err) + result = namedtuple(template.__class__.__name__, dict.keys())(*dict.values()) + return result + def validate_request(schema: T, request: Request, method="POST") -> T: # create schema object