WIP: Add view
This commit is contained in:
parent
a3d65eb78d
commit
603c0544c2
|
|
@ -10,6 +10,9 @@ from django.views import defaults as default_views
|
|||
from django.views.decorators.csrf import csrf_exempt
|
||||
from django_ratelimit.exceptions import Ratelimited
|
||||
from graphene_django.views import GraphQLView
|
||||
from wagtail import urls as wagtail_urls
|
||||
from wagtail.admin import urls as wagtailadmin_urls
|
||||
from wagtail.documents import urls as media_library_urls
|
||||
|
||||
from vbv_lernwelt.api.directory import list_entities
|
||||
from vbv_lernwelt.api.user import (
|
||||
|
|
@ -52,6 +55,7 @@ from vbv_lernwelt.edoniq_test.views import (
|
|||
from vbv_lernwelt.feedback.views import (
|
||||
get_expert_feedbacks_for_course,
|
||||
get_feedback_for_circle,
|
||||
export_feedback_for_course_session,
|
||||
)
|
||||
from vbv_lernwelt.files.views import presign
|
||||
from vbv_lernwelt.importer.views import (
|
||||
|
|
@ -61,9 +65,6 @@ from vbv_lernwelt.importer.views import (
|
|||
)
|
||||
from vbv_lernwelt.media_files.views import user_image
|
||||
from vbv_lernwelt.notify.views import email_notification_settings
|
||||
from wagtail import urls as wagtail_urls
|
||||
from wagtail.admin import urls as wagtailadmin_urls
|
||||
from wagtail.documents import urls as media_library_urls
|
||||
|
||||
|
||||
class SignedIntConverter(IntConverter):
|
||||
|
|
@ -171,6 +172,9 @@ urlpatterns = [
|
|||
name='storage_presign'),
|
||||
|
||||
# feedback
|
||||
path(r'api/core/feedback/export/<str:course_session_id>/',
|
||||
export_feedback_for_course_session,
|
||||
name='export_feedback_for_course_session'),
|
||||
path(r'api/core/feedback/<str:course_session_id>/summary/',
|
||||
get_expert_feedbacks_for_course,
|
||||
name='feedback_summary'),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from datetime import datetime
|
||||
from io import BytesIO
|
||||
from itertools import groupby
|
||||
from operator import attrgetter
|
||||
|
||||
|
|
@ -28,32 +29,48 @@ logger = structlog.get_logger(__name__)
|
|||
|
||||
@click.command()
|
||||
@click.argument("course_session_id")
|
||||
def command(course_session_id):
|
||||
@click.option(
|
||||
"--save-as-file/--no-save-as-file",
|
||||
default=True,
|
||||
help="`save-as-file` to save the file, `no-save-as-file` returns bytes. Default is `save-as-file`.",
|
||||
)
|
||||
def command(course_session_id, save_as_file):
|
||||
# using the output from call_command was a bit cumbersome, so this is just a wrapper for the actual function
|
||||
export_feedback(course_session_id, save_as_file)
|
||||
|
||||
|
||||
def export_feedback(course_session_id: str, save_as_file: bool):
|
||||
wb = Workbook()
|
||||
|
||||
# remove the first sheet is just easier than keeping track of the active sheet
|
||||
wb.remove_sheet(wb.active)
|
||||
# Create another sheet
|
||||
|
||||
feedbacks = FeedbackResponse.objects.filter(
|
||||
course_session_id=course_session_id
|
||||
).order_by("circle")
|
||||
grouped_feedbacks = groupby(feedbacks, key=attrgetter("circle"))
|
||||
|
||||
for circle, group_feedbacks in grouped_feedbacks:
|
||||
group_feedbacks = list(group_feedbacks)
|
||||
logger.debug(
|
||||
"export_feedback_for_circle",
|
||||
data={
|
||||
"circle": circle.title,
|
||||
"course_session_id": course_session_id,
|
||||
"count": sum(1 for _ in group_feedbacks),
|
||||
"count": len(group_feedbacks),
|
||||
},
|
||||
label="feedback_export",
|
||||
)
|
||||
create_sheet(wb, circle.title, group_feedbacks)
|
||||
|
||||
today_date = datetime.today().strftime("%Y-%m-%d")
|
||||
if save_as_file:
|
||||
wb.save(make_export_filename())
|
||||
else:
|
||||
output = BytesIO()
|
||||
wb.save(output)
|
||||
|
||||
# Set the filename with today's date
|
||||
filename = f"feedback_export_{today_date}.xlsx"
|
||||
wb.save("example.xlsx")
|
||||
output.seek(0)
|
||||
return output.getvalue()
|
||||
|
||||
|
||||
def create_sheet(wb: Workbook, title: str, data: list[FeedbackResponse]):
|
||||
|
|
@ -72,3 +89,8 @@ def add_rows(sheet, data):
|
|||
for col_idx, question in enumerate(VV_FEEDBACK_QUESTIONS, start=2):
|
||||
response = feedback.data.get(question[0], "")
|
||||
sheet.cell(row=row_idx, column=col_idx, value=response)
|
||||
|
||||
|
||||
def make_export_filename():
|
||||
today_date = datetime.today().strftime("%Y-%m-%d")
|
||||
return f"feedback_export_{today_date}.xlsx"
|
||||
|
|
|
|||
|
|
@ -1,10 +1,14 @@
|
|||
import itertools
|
||||
|
||||
import structlog
|
||||
from rest_framework.decorators import api_view
|
||||
from django.http import HttpResponse
|
||||
from rest_framework import authentication
|
||||
from rest_framework.decorators import api_view, authentication_classes, permission_classes
|
||||
from rest_framework.exceptions import PermissionDenied
|
||||
from rest_framework.permissions import IsAdminUser
|
||||
from rest_framework.response import Response
|
||||
|
||||
from vbv_lernwelt.feedback.management.commands.export_feedback import export_feedback, make_export_filename
|
||||
from vbv_lernwelt.feedback.models import FeedbackResponse
|
||||
from vbv_lernwelt.feedback.utils import feedback_users
|
||||
from vbv_lernwelt.iam.permissions import is_course_session_expert
|
||||
|
|
@ -78,3 +82,16 @@ def get_feedback_for_circle(request, course_session_id, circle_id):
|
|||
feedback_data["questions"][field].append(data)
|
||||
|
||||
return Response(status=200, data=feedback_data)
|
||||
|
||||
|
||||
@api_view(["GET"])
|
||||
@authentication_classes((authentication.SessionAuthentication,))
|
||||
@permission_classes((IsAdminUser,))
|
||||
def export_feedback_for_course_session(request, course_session_id):
|
||||
excel_bytes = export_feedback(course_session_id, False)
|
||||
|
||||
response = HttpResponse(content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
|
||||
response['Content-Disposition'] = f"attachment; filename={make_export_filename()}"
|
||||
response.write(excel_bytes)
|
||||
|
||||
return response
|
||||
|
|
|
|||
Loading…
Reference in New Issue