feat: add language filter for quizzes to match user locale

This commit is contained in:
akhdanre 2025-05-26 17:56:31 +07:00
parent d46b1e934e
commit cbdce3da20
7 changed files with 91 additions and 29 deletions

View File

@ -63,7 +63,12 @@ def get_quiz_populer(
): ):
page = request.args.get("page") page = request.args.get("page")
limit = request.args.get("limit") limit = request.args.get("limit")
return controller.get_quiz_populer(page=page, limit=limit) lang_code = request.args.get("lang_code") or "id"
return controller.get_quiz_populer(
page=page,
limit=limit,
lang_code=lang_code,
)
@quiz_bp.route("/recommendation", methods=["GET"]) @quiz_bp.route("/recommendation", methods=["GET"])
@ -74,7 +79,13 @@ def get_quiz_recommendation(
user_id = request.args.get("user_id") user_id = request.args.get("user_id")
page = request.args.get("page") page = request.args.get("page")
limit = request.args.get("limit") limit = request.args.get("limit")
return controller.get_quiz_recommendation(user_id=user_id, page=page, limit=limit) lang_code = request.args.get("lang_code") or "id"
return controller.get_quiz_recommendation(
user_id=user_id,
page=page,
limit=limit,
lang_code=lang_code,
)
@quiz_bp.route("/user/<user_id>", methods=["GET"]) @quiz_bp.route("/user/<user_id>", methods=["GET"])
@ -94,6 +105,7 @@ def search_quiz(controller: QuizController = Provide[Container.quiz_controller])
subject_id = request.args.get("subject_id") subject_id = request.args.get("subject_id")
page = int(request.args.get("page", 1)) page = int(request.args.get("page", 1))
limit = int(request.args.get("limit", 10)) limit = int(request.args.get("limit", 10))
lang_code = request.args.get("lang_code") or "id"
return controller.search_quiz( return controller.search_quiz(
keyword=keyword, subject_id=subject_id, page=page, limit=limit keyword=keyword, subject_id=subject_id, page=page, limit=limit

View File

@ -94,11 +94,15 @@ class QuizController:
except Exception as e: except Exception as e:
return make_error_response(e) return make_error_response(e)
def get_quiz_populer(self, page, limit): def get_quiz_populer(self, page, limit, lang_code):
try: try:
page = int(page) if page is not None else 1 page = int(page) if page is not None else 1
limit = int(limit) if limit is not None else 3 limit = int(limit) if limit is not None else 3
result = self.quiz_service.get_quiz_populer(page=page, limit=limit) result = self.quiz_service.get_quiz_populer(
page=page,
limit=limit,
lang_code=lang_code,
)
return make_response(message="success retrieve populer quiz", data=result) return make_response(message="success retrieve populer quiz", data=result)
except DataNotFoundException as e: except DataNotFoundException as e:
return make_response(message=e.message, status_code=e.status_code) return make_response(message=e.message, status_code=e.status_code)
@ -111,14 +115,16 @@ class QuizController:
except Exception as e: except Exception as e:
return make_error_response(e) return make_error_response(e)
def get_quiz_recommendation(self, user_id, page, limit): def get_quiz_recommendation(self, user_id, page, limit, lang_code):
try: try:
page = int(page) if page is not None else 1 page = int(page) if page is not None else 1
limit = int(limit) if limit is not None else 3 limit = int(limit) if limit is not None else 3
result = self.quiz_service.get_quiz_recommendation( result = self.quiz_service.get_quiz_recommendation(
user_id=user_id, user_id=user_id,
page=page, page=page,
limit=limit, limit=limit,
lang_code=lang_code,
) )
return make_response(message="success retrieve populer quiz", data=result) return make_response(message="success retrieve populer quiz", data=result)
except DataNotFoundException as e: except DataNotFoundException as e:

View File

@ -67,6 +67,7 @@ class QuizMapper:
description=schema.description, description=schema.description,
is_public=schema.is_public, is_public=schema.is_public,
date=datetime, date=datetime,
language_code=schema.lang_code,
total_quiz=len(schema.question_listings), total_quiz=len(schema.question_listings),
limit_duration=total_duration, limit_duration=total_duration,
question_listings=[ question_listings=[

View File

@ -7,6 +7,7 @@ from tensorflow.keras.preprocessing.text import tokenizer_from_json # type: ign
import re import re
class AnswerGenerationRepository: class AnswerGenerationRepository:
MODEL_PATH = "app/lstm_model/question_generation/qa_lstm_model_final_v2.keras" MODEL_PATH = "app/lstm_model/question_generation/qa_lstm_model_final_v2.keras"
TOKENIZER_PATH = "app/lstm_model/question_generation/qa_tokenizers_v2.json" TOKENIZER_PATH = "app/lstm_model/question_generation/qa_tokenizers_v2.json"

View File

@ -98,30 +98,57 @@ class QuizRepository:
return self.collection.count_documents({"author_id": user_id}) return self.collection.count_documents({"author_id": user_id})
def get_top_played_quizzes( def get_top_played_quizzes(
self, page: int = 1, limit: int = 3, is_public: bool = True self,
page: int = 1,
limit: int = 3,
is_public: bool = True,
lang_code: str = "id",
) -> List[QuizEntity]: ) -> List[QuizEntity]:
skip = (page - 1) * limit skip = (page - 1) * limit
cursor = ( cursor = (
self.collection.find({"is_public": is_public}) self.collection.find(
{
"is_public": is_public,
"language_code": lang_code,
}
)
.sort("total_user_playing", -1) .sort("total_user_playing", -1)
.skip(skip) .skip(skip)
.limit(limit) .limit(limit)
) )
return [QuizEntity(**doc) for doc in cursor] return [QuizEntity(**doc) for doc in cursor]
def get_random_quizzes(self, limit: int = 3) -> List[QuizEntity]: def get_random_quizzes(
self,
limit: int = 3,
lang_code: str = "id",
) -> List[QuizEntity]:
pipeline = [ pipeline = [
{"$match": {"is_public": True}}, {
"$match": {
"is_public": True,
"language_code": lang_code,
}
},
{"$sample": {"size": limit}}, {"$sample": {"size": limit}},
] ]
cursor = self.collection.aggregate(pipeline) cursor = self.collection.aggregate(pipeline)
return [QuizEntity(**doc) for doc in cursor] return [QuizEntity(**doc) for doc in cursor]
def get_random_quizzes_by_subjects( def get_random_quizzes_by_subjects(
self, subject_ids: List[str], limit: int = 3 self,
subject_ids: List[str],
limit: int = 3,
lang_code: str = "id",
) -> List[QuizEntity]: ) -> List[QuizEntity]:
pipeline = [ pipeline = [
{"$match": {"subject_id": {"$in": subject_ids}, "is_public": True}}, {
"$match": {
"subject_id": {"$in": subject_ids},
"is_public": True,
"language_code": lang_code,
}
},
{"$sample": {"size": limit}}, {"$sample": {"size": limit}},
] ]
cursor = self.collection.aggregate(pipeline) cursor = self.collection.aggregate(pipeline)

View File

@ -7,6 +7,7 @@ from .quiz_item_schema import QuestionItemSchema
class QuizCreateSchema(BaseModel): class QuizCreateSchema(BaseModel):
title: str title: str
description: Optional[str] = None description: Optional[str] = None
lang_code: str = "id"
is_public: bool = False is_public: bool = False
subject_id: str subject_id: str
author_id: Optional[str] = None author_id: Optional[str] = None

View File

@ -14,8 +14,6 @@ from app.exception import DataNotFoundException, ValidationException
from app.mapper import QuizMapper from app.mapper import QuizMapper
from app.helpers import DatetimeUtil from app.helpers import DatetimeUtil
from flask import current_app
class QuizService: class QuizService:
def __init__( def __init__(
@ -105,9 +103,14 @@ class QuizService:
def delete_quiz(self, quiz_id): def delete_quiz(self, quiz_id):
return self.quiz_repository.delete(quiz_id) return self.quiz_repository.delete(quiz_id)
def get_quiz_populer(self, page: int, limit: int): def get_quiz_populer(self, page: int, limit: int, lang_code: str):
data = self.quiz_repository.get_top_played_quizzes(
page=page,
limit=limit,
lang_code=lang_code,
)
data = self.quiz_repository.get_top_played_quizzes(page=page, limit=limit)
if not data: if not data:
raise DataNotFoundException("Quiz not found") raise DataNotFoundException("Quiz not found")
@ -122,25 +125,36 @@ class QuizService:
) )
return result return result
def get_quiz_recommendation(self, user_id: str, page: int, limit: int): def get_quiz_recommendation(
if not user_id: self,
quiz_data = self.quiz_repository.get_random_quizzes(limit=limit) user_id: str,
else: page: int,
limit: int,
lang_code: str,
):
quiz_data = []
if user_id:
user_answer = self.answer_repository.get_by_user(user_id=user_id) user_answer = self.answer_repository.get_by_user(user_id=user_id)
if not user_answer: if user_answer:
return []
quiz_ids = list({answer.quiz_id for answer in user_answer}) quiz_ids = list({answer.quiz_id for answer in user_answer})
quiz_work = self.quiz_repository.get_by_ids(quiz_ids) quiz_work = self.quiz_repository.get_by_ids(quiz_ids)
if not quiz_work: if quiz_work:
return []
quiz_subjects = list({quiz.subject_id for quiz in quiz_work}) quiz_subjects = list({quiz.subject_id for quiz in quiz_work})
if quiz_subjects:
quiz_data = self.quiz_repository.get_random_quizzes_by_subjects( quiz_data = self.quiz_repository.get_random_quizzes_by_subjects(
subject_ids=quiz_subjects, limit=limit subject_ids=quiz_subjects,
limit=limit,
lang_code=lang_code,
)
if not quiz_data:
quiz_data = self.quiz_repository.get_random_quizzes(
limit=limit,
lang_code=lang_code,
) )
result = [] result = []