Skip to content

Commit

Permalink
[PPS] Working v2 ugly reports
Browse files Browse the repository at this point in the history
  • Loading branch information
pritamps committed Jul 31, 2024
1 parent 6b673a8 commit ddcf660
Show file tree
Hide file tree
Showing 5 changed files with 184 additions and 16 deletions.
15 changes: 13 additions & 2 deletions app/db/reports_db.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from botocore.exceptions import ClientError
from boto3.resources.base import ServiceResource
from boto3.dynamodb.conditions import Key
from boto3.resources.base import ServiceResource
from botocore.exceptions import ClientError


class ReportsDB:
Expand Down Expand Up @@ -33,6 +33,17 @@ def get_student_quiz_report(self, user_id, session_id):
except ClientError as e:
raise ValueError(e.response["Error"]["Message"])

def get_student_quiz_report_v2(self, user_id, session_id):
try:
table = self.__db.Table("student_quiz_reports_v2")
response = table.query(
KeyConditionExpression=Key("session_id").eq(session_id)
& Key("user_id").eq(user_id)
)
return response["Items"]
except ClientError as e:
raise ValueError(e.response["Error"]["Message"])

def get_student_reports(self, user_id):
"""
Returns all student reports for a given user ID.
Expand Down
7 changes: 4 additions & 3 deletions app/db/sessions_db.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import base64
import json
import os

from dotenv import load_dotenv
from google.cloud import firestore
import os
import json
import base64
from google.cloud.firestore_v1.base_query import FieldFilter


Expand Down
92 changes: 87 additions & 5 deletions app/routers/student_quiz_reports.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
from fastapi import APIRouter, Request
from fastapi.templating import Jinja2Templates
from fastapi import HTTPException, Depends
from collections import OrderedDict
from typing import Optional, Union
from urllib.parse import unquote
from typing import Union, Optional
from db.reports_db import ReportsDB

from auth import verify_token
from db.reports_db import ReportsDB
from fastapi import APIRouter, Depends, HTTPException, Request
from fastapi.security.api_key import APIKeyHeader
from fastapi.templating import Jinja2Templates

ROW_NAMES = OrderedDict()
ROW_NAMES = {
Expand Down Expand Up @@ -220,4 +220,86 @@ def student_quiz_report(request: Request, session_id: str, user_id: str):
{"request": request, "report_data": report_data},
)

@api_router.get("/student_quiz_report/v2/{session_id}/{user_id}")
def student_quiz_report_v2(request: Request, session_id: str, user_id: str):
"""
Returns a student quiz report (V2) for a given session ID and user ID.
Args:
request (Request): The request object.
session_id (str): The session ID.
user_id (str): The user ID.
Raises:
HTTPException: If session ID or user ID is not specified.
Returns:
TemplateResponse: The student quiz report template response.
"""
if session_id is None or user_id is None:
raise HTTPException(
status_code=400,
detail="Session ID and User ID have to be specified",
)
# decoding URL encoded values. As this information is coming through a URL,
# it's possible that the strings are URL encoded.
session_id = unquote(session_id)
user_id = unquote(user_id)
try:
data = self.__reports_db.get_student_quiz_report_v2(user_id, session_id)
except KeyError:
raise HTTPException(
status_code=400,
detail="No student_quiz_report found. Unknown error occurred.",
)

if len(data) == 0:
# no data
error_data = {
"session_id": session_id,
"user_id": user_id,
"error_message": "No report found. Please contact admin.",
"status_code": 404,
}
return self._templates.TemplateResponse(
"error.html", {"request": request, "error_data": error_data}
)

return self._templates.TemplateResponse(
"student_quiz_report_v2.html",
{"request": request, "report_data": data[0]},
)

# return data
# report_data = {}
# report_data["student_name"] = ""
# test_id = data[0]["test_id"]
# user_id = data[0]["user_id"]

# report_data["student_id"] = user_id
# if "platform" in data[0] and data[0]["platform"] == "quizengine":
# report_data["test_link"] = QUIZ_URL.format(
# quiz_id=test_id, user_id=user_id, api_key=AF_API_KEY
# )

# section_reports = []
# overall_performance = {}
# for section in data:
# parsed_section_data = _parse_section_data(section)
# if section["section"] == "overall":
# overall_performance = parsed_section_data
# report_data["percentage"] = parsed_section_data["table_data"][
# "Percentage"
# ]
# report_data["test_name"] = section["test_name"]
# report_data["test_date"] = section["start_date"]
# else:
# section_reports.append(parsed_section_data)
# report_data["overall_performance"] = overall_performance
# report_data["section_reports"] = section_reports
# return self._templates.TemplateResponse(
# "student_quiz_report.html",
# {"request": request, "report_data": report_data},
# )

return api_router
80 changes: 80 additions & 0 deletions app/templates/student_quiz_report_v2.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
{% extends "layout.html" %}
{% block title %}Index{% endblock %}

{% block content %}

<div id="name_card">
{% if report_data["name"] != "" %}
<p>Name: {{report_data["name"]}}
{% endif %}
<p>Student ID: {{report_data["user_id"]}}
</div>

<section id="overall_performance">
<div id="section_heading">Overall Performance</div>
{% set score_details = report_data["sections"] %}

<table id="score_details">
<table border="1" id="score_details">
<tr>
<th></th>
{% for subject in score_details %}
<th>{{ 'Total' if subject == 'overall' else subject }}</th>
{% endfor %}
</tr>
<tr>
<td>Score</td>
{% for subject in score_details %}
<td>{{ score_details[subject]['marks_scored']|round(0, 'floor')|int }}</td>
{% endfor %}
</tr>
<tr>
<td>Attempt Rate</td>
{% for subject in score_details %}
<td>{{ "%.2f%%"|format(score_details[subject]['attempt_rate']) }}</td>
{% endfor %}
</tr>
<tr>
<td>Accuracy</td>
{% for subject in score_details %}
{% set accuracy = score_details[subject]['accuracy']|float %}
{% set green = 255 * (accuracy / 100.0) %}
{% set red = 255 * (1 - accuracy / 100.0) %}
{% set color = "rgb({},{},0)".format(red|int, green|int) %}
<td style="background-color: {{ color }};">
{{ "%.2f%%"|format(accuracy) }}
</td>
</td>
{% endfor %}
</tr>
</table>
</table>
</section>

<section id="milestones">
{% set milestones = report_data["milestones"] %}

{% for milestone in milestones %}
<h2>{{ milestone.title }}</h2>
{% for subject, details in milestone.items() if subject not in ['milestone', 'title'] %}
<h3>{{ subject }}</h3>
<table id="score_details">
<tr>
<th>Chapter</th>
<th>Question No.</th>
<th>Your Response</th>
</tr>
{% for detail in details %}
<tr>
<td>{{ detail.chapter }}</td>
<td>{{ detail.question_number }}</td>
<td class="{% if detail.response == 'Correct' %}correct{% elif detail.response == 'Incorrect' %}incorrect{% else %}skipped{% endif %}">{{ detail.response }}</td>
</tr>
{% endfor %}
</table>
{% endfor %}
{% endfor %}

</section>

{% endblock %}
6 changes: 0 additions & 6 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@ services:
ports:
- 8001:8001
environment:
- DYNAMO_ENDPOINT=http://dynamodb-local:8000
- AWS_REGION=ap-south-1
- AWS_ACCESS_KEY_ID=local
- AWS_SECRET_ACCESS_KEY=local
depends_on:
- dynamodb-local
app:
Expand All @@ -39,8 +35,6 @@ services:
- "5050:5050"
depends_on:
- dynamodb-local
environment:
- env_file = ./.env.local
volumes:
dynamodb_data:
external: true

0 comments on commit ddcf660

Please sign in to comment.