feat: quiz recomendation

This commit is contained in:
akhdanre 2025-05-01 10:53:50 +07:00
parent 650c4d7b03
commit a2df303e02
10 changed files with 85 additions and 10 deletions

View File

@ -46,7 +46,9 @@ def get_answer(controller: QuizController = Provide[Container.quiz_controller]):
def get_quiz_recommendation(
controller: QuizController = Provide[Container.quiz_controller],
):
return controller.get_quiz_recommendation()
page = request.args.get("page")
limit = request.args.get("limit")
return controller.get_quiz_recommendation(page=page, limit=limit)
@quiz_bp.route("/user/<user_id>", methods=["GET"])

View File

@ -104,3 +104,26 @@ class QuizController:
)
except Exception as e:
return make_error_response(e)
def get_quiz_recommendation(self, page, limit):
try:
# Convert to int
page = int(page)
limit = int(limit)
# Validate input
if page <= 0 or limit <= 0:
raise ValueError("Page and limit must be greater than 0.")
result = self.quiz_service.get_quiz_recommendation(page=page, limit=limit)
return make_response(
message="success retrieve recommendation quiz", data=result
)
except ValueError as e:
return make_response(message=str(e), data=None, status_code=400)
except ValidationError as e:
return make_response(
message="validation error", data=json.loads(e.json()), status_code=400
)
except Exception as e:
return make_error_response(e)

View File

@ -28,7 +28,11 @@ class Container(containers.DeclarativeContainer):
# services
auth_service = providers.Factory(AuthService, user_repository)
user_service = providers.Factory(UserService, user_repository)
quiz_service = providers.Factory(QuizService, quiz_repository)
quiz_service = providers.Factory(
QuizService,
quiz_repository,
user_repository,
)
answer_service = providers.Factory(
AnswerService,
answer_repository,

View File

@ -14,7 +14,9 @@ def map_question_entity_to_schema(entity: QuestionItemEntity) -> QuestionItemSch
def map_quiz_entity_to_schema(entity: QuizEntity) -> QuizGetSchema:
print(entity.id)
return QuizGetSchema(
id=str(entity.id),
author_id=entity.author_id,
title=entity.title,
description=entity.description,

View File

@ -74,3 +74,15 @@ class QuizRepository:
def count_by_user_id(self, user_id: str) -> int:
return self.collection.count_documents({"author_id": user_id})
def get_top_played_quizzes(
self, page: int = 1, limit: int = 3, is_public: bool = True
) -> List[QuizEntity]:
skip = (page - 1) * limit
cursor = (
self.collection.find({"is_public": is_public})
.sort("total_user_playing", -1)
.skip(skip)
.limit(limit)
)
return [QuizEntity(**doc) for doc in cursor]

View File

@ -4,6 +4,7 @@ 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 RecomendationResponse
__all__ = [
"QuizCreationResponse",
@ -13,4 +14,5 @@ __all__ = [
"HistoryResultSchema",
"QuizHistoryResponse",
"QuestionResult",
"RecomendationResponse",
]

View File

@ -5,6 +5,7 @@ from .question_item_schema import QuestionItemSchema
class QuizGetSchema(BaseModel):
id: str
author_id: str
title: str
description: Optional[str] = None

View File

@ -0,0 +1,10 @@
from pydantic import BaseModel
class RecomendationResponse(BaseModel):
quiz_id: str
author_id: str
author_name: str
title: str
description: str
date: str

View File

@ -25,10 +25,11 @@ class AnswerService:
def create_answer(self, answer_data: UserAnswerSchema):
quiz_data = self.quiz_repository.get_by_id(answer_data.quiz_id)
if not quiz_data:
raise ValidationException(message="Quiz not found")
user_data = self.user_repositroy.get_user_by_id(answer_data.user_id)
if not user_data:
raise ValidationException(message="user is not registered")
total_quiz_played = quiz_data.total_user_playing + 1
self.quiz_repository.update_user_playing(
quiz_id=quiz_data.id, total_user=total_quiz_played

View File

@ -1,16 +1,17 @@
from typing import List
from repositories import QuizRepository
from repositories import QuizRepository, UserRepository
from schemas import QuizGetSchema
from schemas.requests import QuizCreateSchema
from schemas.response import UserQuizListResponse
from schemas.response import UserQuizListResponse, RecomendationResponse
from exception import DataNotFoundException
from mapper import map_quiz_entity_to_schema
from exception import ValidationException
class QuizService:
def __init__(self, quiz_repository=QuizRepository):
def __init__(self, quiz_repository=QuizRepository, user_repository=UserRepository):
self.quiz_repository = quiz_repository
self.user_repostory = user_repository
def get_quiz(self, quiz_id) -> QuizGetSchema:
data = self.quiz_repository.get_by_id(quiz_id)
@ -45,9 +46,26 @@ class QuizService:
def delete_quiz(self, quiz_id):
return self.quiz_repository.delete(quiz_id)
def quiz_recommendation(self):
data = self.quiz_repository
if data is None:
def get_quiz_recommendation(self, page: int = 1, limit: int = 3):
page = page or 1
limit = limit or 3
data = self.quiz_repository.get_top_played_quizzes(page=page, limit=limit)
if not data:
raise DataNotFoundException("Quiz not found")
return map_quiz_entity_to_schema(data)
result = []
for quiz in data:
author = self.user_repostory.get_user_by_id(user_id=quiz.author_id)
result.append(
RecomendationResponse(
quiz_id=str(quiz.id),
author_id=str(author.id),
author_name=author.name,
title=quiz.title,
description=quiz.description,
date=quiz.date.strftime("%d-%B-%Y"),
)
)
return result