feat: adding recomendation
This commit is contained in:
parent
a099da34f4
commit
faf6a0f4b9
|
@ -56,14 +56,25 @@ def get_answer(controller: QuizController = Provide[Container.quiz_controller]):
|
|||
)
|
||||
|
||||
|
||||
@quiz_bp.route("/recomendation", methods=["GET"])
|
||||
@quiz_bp.route("/populer", methods=["GET"])
|
||||
@inject
|
||||
def get_quiz_recommendation(
|
||||
def get_quiz_populer(
|
||||
controller: QuizController = Provide[Container.quiz_controller],
|
||||
):
|
||||
page = request.args.get("page")
|
||||
limit = request.args.get("limit")
|
||||
return controller.get_quiz_recommendation(page=page, limit=limit)
|
||||
return controller.get_quiz_populer(page=page, limit=limit)
|
||||
|
||||
|
||||
@quiz_bp.route("/recommendation", methods=["GET"])
|
||||
@inject
|
||||
def get_quiz_recommendation(
|
||||
controller: QuizController = Provide[Container.quiz_controller],
|
||||
):
|
||||
user_id = request.args.get("user_id")
|
||||
page = request.args.get("page")
|
||||
limit = request.args.get("limit")
|
||||
return controller.get_quiz_recommendation(user_id=user_id, page=page, limit=limit)
|
||||
|
||||
|
||||
@quiz_bp.route("/user/<user_id>", methods=["GET"])
|
||||
|
|
|
@ -43,9 +43,9 @@ class QuizController:
|
|||
except Exception as e:
|
||||
return make_error_response(e)
|
||||
|
||||
def quiz_recomendation(self):
|
||||
def quiz_populer(self):
|
||||
try:
|
||||
result = self.quiz_service.get_quiz_recommendation()
|
||||
result = self.quiz_service.get_quiz_populer()
|
||||
if not result:
|
||||
return make_response(message="Quiz not found", status_code=404)
|
||||
return make_response(message="Quiz Found", data=result.model_dump())
|
||||
|
@ -94,14 +94,33 @@ class QuizController:
|
|||
except Exception as e:
|
||||
return make_error_response(e)
|
||||
|
||||
def get_quiz_recommendation(self, page, limit):
|
||||
def get_quiz_populer(self, page, limit):
|
||||
try:
|
||||
page = int(page) if page is not None else 1
|
||||
limit = int(limit) if limit is not None else 3
|
||||
result = self.quiz_service.get_quiz_recommendation(page=page, limit=limit)
|
||||
result = self.quiz_service.get_quiz_populer(page=page, limit=limit)
|
||||
return make_response(message="success retrieve populer quiz", data=result)
|
||||
except DataNotFoundException as e:
|
||||
return make_response(message=e.message, status_code=e.status_code)
|
||||
except ValueError as e:
|
||||
return make_response(message=str(e), data=None, status_code=400)
|
||||
except ValidationError as e:
|
||||
return make_response(
|
||||
message="success retrieve recommendation quiz", data=result
|
||||
message="validation error", data=json.loads(e.json()), status_code=400
|
||||
)
|
||||
except Exception as e:
|
||||
return make_error_response(e)
|
||||
|
||||
def get_quiz_recommendation(self, user_id, page, limit):
|
||||
try:
|
||||
page = int(page) if page is not None else 1
|
||||
limit = int(limit) if limit is not None else 3
|
||||
result = self.quiz_service.get_quiz_recommendation(
|
||||
user_id=user_id,
|
||||
page=page,
|
||||
limit=limit,
|
||||
)
|
||||
return make_response(message="success retrieve populer quiz", data=result)
|
||||
except DataNotFoundException as e:
|
||||
return make_response(message=e.message, status_code=e.status_code)
|
||||
except ValueError as e:
|
||||
|
|
|
@ -75,6 +75,7 @@ class Container(containers.DeclarativeContainer):
|
|||
quiz_repository,
|
||||
user_repository,
|
||||
subject_repository,
|
||||
answer_repository,
|
||||
)
|
||||
answer_service = providers.Factory(
|
||||
AnswerService,
|
||||
|
|
|
@ -76,7 +76,7 @@ class QuizMapper:
|
|||
)
|
||||
|
||||
@staticmethod
|
||||
def quiz_to_recomendation_mapper(
|
||||
def quiz_to_populer_mapper(
|
||||
quiz_entity: QuizEntity,
|
||||
user_entity: UserEntity,
|
||||
) -> ListingQuizResponse:
|
||||
|
|
|
@ -14,8 +14,9 @@ class QuizEntity(BaseModel):
|
|||
is_public: bool = False
|
||||
date: datetime
|
||||
total_quiz: int = 0
|
||||
limit_duration: Optional[int] = 0 # in
|
||||
limit_duration: Optional[int] = 0
|
||||
total_user_playing: int = 0
|
||||
language_code: Optional[str] = "id"
|
||||
question_listings: Optional[list[QuestionItemEntity]] = []
|
||||
|
||||
class ConfigDict:
|
||||
|
|
|
@ -20,34 +20,6 @@ class QuizRepository:
|
|||
return QuizEntity(**data)
|
||||
return None
|
||||
|
||||
# def search_by_title_or_category(
|
||||
# self, keyword: str, page: int, page_size: int
|
||||
# ) -> List[QuizEntity]:
|
||||
# skip = (page - 1) * page_size
|
||||
# pipeline = [
|
||||
# {
|
||||
# "$lookup": {
|
||||
# "from": "category",
|
||||
# "localField": "category_id",
|
||||
# "foreignField": "_id",
|
||||
# "as": "category_info",
|
||||
# }
|
||||
# },
|
||||
# {"$unwind": "$category_info"},
|
||||
# {
|
||||
# "$match": {
|
||||
# "$or": [
|
||||
# {"title": {"$regex": keyword, "$options": "i"}},
|
||||
# {"category_info.name": {"$regex": keyword, "$options": "i"}},
|
||||
# ]
|
||||
# }
|
||||
# },
|
||||
# {"$skip": skip},
|
||||
# {"$limit": page_size},
|
||||
# ]
|
||||
# cursor = self.collection.aggregate(pipeline)
|
||||
# return [QuizEntity(**doc) for doc in cursor]
|
||||
|
||||
def search_by_title_or_category(
|
||||
self, keyword: str, subject_id: Optional[str], page: int, page_size: int
|
||||
) -> List[QuizEntity]:
|
||||
|
@ -86,7 +58,6 @@ class QuizRepository:
|
|||
object_ids = [ObjectId(qid) for qid in quiz_ids]
|
||||
cursor = self.collection.find({"_id": {"$in": object_ids}})
|
||||
datas = list(cursor)
|
||||
|
||||
|
||||
if not datas:
|
||||
return None
|
||||
|
@ -137,3 +108,13 @@ class QuizRepository:
|
|||
.limit(limit)
|
||||
)
|
||||
return [QuizEntity(**doc) for doc in cursor]
|
||||
|
||||
def get_random_quizzes_by_subjects(
|
||||
self, subject_ids: List[str], limit: int = 3
|
||||
) -> List[QuizEntity]:
|
||||
pipeline = [
|
||||
{"$match": {"subject_id": {"$in": subject_ids}, "is_public": True}},
|
||||
{"$sample": {"size": limit}},
|
||||
]
|
||||
cursor = self.collection.aggregate(pipeline)
|
||||
return [QuizEntity(**doc) for doc in cursor]
|
||||
|
|
|
@ -4,11 +4,11 @@ from .quiz.question_item_schema import QuestionItemSchema
|
|||
from .quiz.quiz_data_rsp_schema import UserQuizListResponse
|
||||
from .history.history_response import HistoryResultSchema
|
||||
from .history.detail_history_response import QuizHistoryResponse, QuestionResult
|
||||
from .recomendation.recomendation_response_schema import ListingQuizResponse
|
||||
from .subject.get_subject_schema import GetSubjectResponse
|
||||
from .auth.login_response import LoginResponseSchema
|
||||
from .user.user_response_scema import UserResponseSchema
|
||||
from .answer.answer_session_response import AnsweredQuizResponse
|
||||
from .recomendation.recomendation_response_schema import ListingQuizResponse
|
||||
|
||||
__all__ = [
|
||||
"QuizCreationResponse",
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
from typing import List
|
||||
from pydantic import BaseModel
|
||||
from app.schemas.response.recomendation.recomendation_response_schema import (
|
||||
ListingQuizResponse,
|
||||
)
|
||||
from ..recomendation.recomendation_response_schema import ListingQuizResponse
|
||||
|
||||
|
||||
class UserQuizListResponse(BaseModel):
|
||||
|
|
|
@ -1,25 +1,34 @@
|
|||
from app.repositories import QuizRepository, UserRepository, SubjectRepository
|
||||
from app.repositories import (
|
||||
QuizRepository,
|
||||
UserRepository,
|
||||
SubjectRepository,
|
||||
UserAnswerRepository,
|
||||
)
|
||||
from app.schemas.requests import QuizCreateSchema
|
||||
from app.schemas.response import (
|
||||
UserQuizListResponse,
|
||||
ListingQuizResponse,
|
||||
QuizGetSchema,
|
||||
ListingQuizResponse,
|
||||
)
|
||||
from app.exception import DataNotFoundException, ValidationException
|
||||
from app.mapper import QuizMapper
|
||||
from app.helpers import DatetimeUtil
|
||||
|
||||
from flask import current_app
|
||||
|
||||
|
||||
class QuizService:
|
||||
def __init__(
|
||||
self,
|
||||
quiz_repository=QuizRepository,
|
||||
user_repository=UserRepository,
|
||||
subject_repository=SubjectRepository,
|
||||
quiz_repository: QuizRepository,
|
||||
user_repository: UserRepository,
|
||||
subject_repository: SubjectRepository,
|
||||
answer_repository: UserAnswerRepository,
|
||||
):
|
||||
self.quiz_repository = quiz_repository
|
||||
self.user_repostory = user_repository
|
||||
self.subject_repository = subject_repository
|
||||
self.answer_repository = answer_repository
|
||||
|
||||
def get_quiz(self, quiz_id) -> QuizGetSchema:
|
||||
data = self.quiz_repository.get_by_id(quiz_id)
|
||||
|
@ -46,7 +55,7 @@ class QuizService:
|
|||
if author is None:
|
||||
continue
|
||||
mapped_quizzes.append(
|
||||
QuizMapper.quiz_to_recomendation_mapper(
|
||||
QuizMapper.quiz_to_populer_mapper(
|
||||
quiz_entity=quiz,
|
||||
user_entity=author,
|
||||
)
|
||||
|
@ -63,13 +72,9 @@ class QuizService:
|
|||
|
||||
total_user_quiz = self.quiz_repository.count_by_user_id(user_id)
|
||||
|
||||
|
||||
|
||||
user = self.user_repostory.get_user_by_id(user_id)
|
||||
|
||||
quiz_data = [
|
||||
QuizMapper.quiz_to_recomendation_mapper(quiz, user) for quiz in quizzes
|
||||
]
|
||||
quiz_data = [QuizMapper.quiz_to_populer_mapper(quiz, user) for quiz in quizzes]
|
||||
|
||||
return UserQuizListResponse(total=total_user_quiz, quizzes=quiz_data)
|
||||
|
||||
|
@ -100,7 +105,7 @@ class QuizService:
|
|||
def delete_quiz(self, quiz_id):
|
||||
return self.quiz_repository.delete(quiz_id)
|
||||
|
||||
def get_quiz_recommendation(self, page: int, limit: int):
|
||||
def get_quiz_populer(self, page: int, limit: int):
|
||||
|
||||
data = self.quiz_repository.get_top_played_quizzes(page=page, limit=limit)
|
||||
if not data:
|
||||
|
@ -110,9 +115,30 @@ class QuizService:
|
|||
for quiz in data:
|
||||
author = self.user_repostory.get_user_by_id(user_id=quiz.author_id)
|
||||
result.append(
|
||||
QuizMapper.quiz_to_recomendation_mapper(
|
||||
QuizMapper.quiz_to_populer_mapper(
|
||||
quiz_entity=quiz,
|
||||
user_entity=author,
|
||||
)
|
||||
)
|
||||
return result
|
||||
|
||||
def get_quiz_recommendation(self, user_id: str, page: int, limit: int):
|
||||
current_app.logger.info("in here is should execute")
|
||||
user_answer = self.answer_repository.get_by_user(user_id=user_id)
|
||||
|
||||
if not user_answer:
|
||||
return []
|
||||
|
||||
quiz_ids = list({answer.quiz_id for answer in user_answer})
|
||||
quiz_work = self.quiz_repository.get_by_ids(quiz_ids)
|
||||
|
||||
if not quiz_work:
|
||||
return []
|
||||
|
||||
quiz_subjects = list({quiz.subject_id for quiz in quiz_work})
|
||||
|
||||
result = self.quiz_repository.get_random_quizzes_by_subjects(
|
||||
subject_ids=quiz_subjects, limit=limit
|
||||
)
|
||||
|
||||
return result
|
||||
|
|
|
@ -225,7 +225,7 @@ paths:
|
|||
"404":
|
||||
$ref: "#/components/responses/NotFound"
|
||||
|
||||
/quiz/recomendation:
|
||||
/quiz/populer:
|
||||
get:
|
||||
summary: Get recommended quizzes
|
||||
description: Returns a list of recommended quizzes for the user
|
||||
|
@ -235,7 +235,7 @@ paths:
|
|||
- $ref: "#/components/parameters/LimitParam"
|
||||
responses:
|
||||
"200":
|
||||
description: Successfully retrieved recommendation quiz list
|
||||
description: Successfully retrieved populer quiz list
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
|
@ -243,7 +243,7 @@ paths:
|
|||
properties:
|
||||
message:
|
||||
type: string
|
||||
example: success retrieve recommendation quiz
|
||||
example: success retrieve populer quiz
|
||||
data:
|
||||
type: array
|
||||
items:
|
||||
|
|
|
@ -114,7 +114,7 @@
|
|||
# assert result.quizzes == []
|
||||
|
||||
|
||||
# def test_get_quiz_recommendation_found(quiz_service, mock_repositories):
|
||||
# def test_get_quiz_populer_found(quiz_service, mock_repositories):
|
||||
# quiz = QuizEntity(
|
||||
# id=ObjectId(),
|
||||
# author_id="user1",
|
||||
|
@ -131,14 +131,14 @@
|
|||
# mock_repositories["quiz_repository"].get_top_played_quizzes.return_value = [quiz]
|
||||
# mock_repositories["user_repository"].get_user_by_id.return_value = MagicMock()
|
||||
|
||||
# result = quiz_service.get_quiz_recommendation(1, 5)
|
||||
# result = quiz_service.get_quiz_populer(1, 5)
|
||||
# assert len(result) == 1
|
||||
|
||||
|
||||
# def test_get_quiz_recommendation_not_found(quiz_service, mock_repositories):
|
||||
# def test_get_quiz_populer_not_found(quiz_service, mock_repositories):
|
||||
# mock_repositories["quiz_repository"].get_top_played_quizzes.return_value = []
|
||||
# with pytest.raises(DataNotFoundException):
|
||||
# quiz_service.get_quiz_recommendation(1, 5)
|
||||
# quiz_service.get_quiz_populer(1, 5)
|
||||
|
||||
|
||||
# def test_update_quiz(quiz_service, mock_repositories):
|
||||
|
|
Loading…
Reference in New Issue