242 lines
7.3 KiB
Python
242 lines
7.3 KiB
Python
import structlog
|
|
from django.shortcuts import get_object_or_404
|
|
from rest_framework.decorators import api_view
|
|
from rest_framework.exceptions import PermissionDenied
|
|
from rest_framework.response import Response
|
|
from wagtail.models import Page
|
|
|
|
from vbv_lernwelt.core.utils import api_page_cache_get_or_set
|
|
from vbv_lernwelt.course.models import (
|
|
CircleDocument,
|
|
CourseCompletion,
|
|
CourseSessionUser,
|
|
)
|
|
from vbv_lernwelt.course.permissions import (
|
|
course_sessions_for_user_qs,
|
|
has_course_access_by_page_request,
|
|
has_course_access,
|
|
is_course_expert,
|
|
is_circle_expert,
|
|
)
|
|
from vbv_lernwelt.course.serializers import (
|
|
CourseCompletionSerializer,
|
|
CourseSessionSerializer,
|
|
DocumentUploadFinishInputSerializer,
|
|
DocumentUploadStartInputSerializer,
|
|
)
|
|
from vbv_lernwelt.course.services import mark_course_completion
|
|
from vbv_lernwelt.files.models import UploadFile
|
|
from vbv_lernwelt.files.services import FileDirectUploadService
|
|
from vbv_lernwelt.learnpath.utils import get_wagtail_type
|
|
|
|
logger = structlog.get_logger(__name__)
|
|
|
|
|
|
@api_view(["GET"])
|
|
def course_page_api_view(request, slug):
|
|
try:
|
|
page = Page.objects.get(slug=slug, locale__language_code="de-CH")
|
|
if not has_course_access_by_page_request(request, page):
|
|
raise PermissionDenied()
|
|
|
|
data = api_page_cache_get_or_set(
|
|
key=request.get_full_path(),
|
|
func=lambda: page.specific.get_serializer_class()(page.specific).data,
|
|
)
|
|
|
|
return Response(data)
|
|
except PermissionDenied as e:
|
|
raise e
|
|
except Exception as e:
|
|
logger.error(e)
|
|
return Response({"error": str(e)}, status=404)
|
|
|
|
|
|
def _request_course_completion(course_id, user_id):
|
|
try:
|
|
response_data = CourseCompletionSerializer(
|
|
CourseCompletion.objects.filter(user_id=user_id, course_id=course_id),
|
|
many=True,
|
|
).data
|
|
|
|
return Response(status=200, data=response_data)
|
|
except PermissionDenied as e:
|
|
raise e
|
|
except Exception as e:
|
|
logger.error(e)
|
|
return Response({"error": str(e)}, status=404)
|
|
|
|
|
|
@api_view(["GET"])
|
|
def request_course_completion(request, course_id):
|
|
if has_course_access(request.user, course_id):
|
|
return _request_course_completion(course_id, request.user.id)
|
|
raise PermissionDenied()
|
|
|
|
|
|
@api_view(["GET"])
|
|
def request_course_completion_for_user(request, course_id, user_id):
|
|
if request.user.id == user_id or is_course_expert(request.user, course_id):
|
|
return _request_course_completion(course_id, user_id)
|
|
raise PermissionDenied()
|
|
|
|
|
|
@api_view(["POST"])
|
|
def mark_course_completion_view(request):
|
|
try:
|
|
page_key = request.data.get("page_key")
|
|
completion_status = request.data.get("completion_status", "success")
|
|
page = Page.objects.get(translation_key=page_key, locale__language_code="de-CH")
|
|
|
|
if not has_course_access_by_page_request(request, page):
|
|
raise PermissionDenied()
|
|
|
|
page_type = get_wagtail_type(page.specific)
|
|
course = page.specific.get_course()
|
|
|
|
mark_course_completion(
|
|
page_key, request.user, completion_status=completion_status
|
|
)
|
|
|
|
response_data = CourseCompletionSerializer(
|
|
CourseCompletion.objects.filter(user=request.user, course_id=course.id),
|
|
many=True,
|
|
).data
|
|
|
|
logger.debug(
|
|
"mark_course_completion successful",
|
|
label="completion_api",
|
|
page_key=page_key,
|
|
page_type=page_type,
|
|
page_slug=page.slug,
|
|
page_title=page.title,
|
|
user_id=request.user.id,
|
|
course_id=course.id,
|
|
completion_status=completion_status,
|
|
)
|
|
|
|
return Response(status=200, data=response_data)
|
|
except PermissionDenied as e:
|
|
raise e
|
|
except Exception as e:
|
|
logger.error(e)
|
|
return Response({"error": str(e)}, status=404)
|
|
|
|
|
|
@api_view(["GET"])
|
|
def get_course_sessions(request):
|
|
try:
|
|
course_sessions = course_sessions_for_user_qs(request.user)
|
|
return Response(
|
|
status=200, data=CourseSessionSerializer(course_sessions, many=True).data
|
|
)
|
|
except PermissionDenied as e:
|
|
raise e
|
|
except Exception as e:
|
|
logger.error(e)
|
|
return Response({"error": str(e)}, status=404)
|
|
|
|
|
|
@api_view(["GET"])
|
|
def get_course_session_users(request, course_slug):
|
|
try:
|
|
course_sessions = course_sessions_for_user_qs(request.user).filter(
|
|
course__slug=course_slug
|
|
)
|
|
qs = CourseSessionUser.objects.filter(course_session__in=course_sessions)
|
|
cockpit_user_csu = qs.filter(user_id=request.user.id)
|
|
|
|
if len(cockpit_user_csu) == 0:
|
|
return Response({"error": "User not found"}, status=404)
|
|
|
|
user_data = [csu.to_dict() for csu in qs.exclude(user_id=request.user.id)]
|
|
|
|
data = {
|
|
"cockpit_user": cockpit_user_csu[0].to_dict()
|
|
| {
|
|
"circles": cockpit_user_csu[0]
|
|
.expert.all()
|
|
.values("id", "title", "slug", "translation_key")
|
|
},
|
|
"users": user_data,
|
|
}
|
|
|
|
return Response(status=200, data=data)
|
|
except PermissionDenied as e:
|
|
raise e
|
|
except Exception as e:
|
|
logger.error(e)
|
|
return Response({"error": str(e)}, status=404)
|
|
|
|
|
|
@api_view(["POST"])
|
|
def document_upload_start(request):
|
|
serializer = DocumentUploadStartInputSerializer(data=request.data)
|
|
serializer.is_valid(raise_exception=True)
|
|
|
|
if not is_circle_expert(
|
|
request.user,
|
|
serializer.validated_data["learning_sequence"],
|
|
serializer.validated_data["course_session"],
|
|
):
|
|
raise PermissionDenied()
|
|
|
|
service = FileDirectUploadService(request.user)
|
|
file, presigned_data = service.start(
|
|
serializer.validated_data["file_name"], serializer.validated_data["file_type"]
|
|
)
|
|
|
|
document = CircleDocument(
|
|
file=file,
|
|
name=serializer.validated_data["name"],
|
|
course_session_id=serializer.validated_data["course_session"],
|
|
learning_sequence_id=serializer.validated_data["learning_sequence"],
|
|
)
|
|
document.save()
|
|
presigned_data["id"] = document.id
|
|
presigned_data["file_id"] = file.id
|
|
|
|
return Response(data=presigned_data)
|
|
|
|
|
|
@api_view(["POST"])
|
|
def document_upload_finish(request):
|
|
serializer = DocumentUploadFinishInputSerializer(data=request.data)
|
|
serializer.is_valid(raise_exception=True)
|
|
|
|
file_id = serializer.validated_data["file_id"]
|
|
file = get_object_or_404(UploadFile, id=file_id)
|
|
|
|
if file.uploaded_by != request.user:
|
|
raise PermissionDenied()
|
|
|
|
service = FileDirectUploadService(request.user)
|
|
service.finish(file=file)
|
|
|
|
return Response({"url": file.url})
|
|
|
|
|
|
@api_view(["POST"])
|
|
def document_direct_upload(request, file_id):
|
|
file = get_object_or_404(UploadFile, id=file_id)
|
|
|
|
file_obj = request.FILES["file"]
|
|
|
|
service = FileDirectUploadService(request.user)
|
|
file = service.upload_local(file=file, file_obj=file_obj)
|
|
|
|
return Response({"url": file.url})
|
|
|
|
|
|
@api_view(["DELETE"])
|
|
def document_delete(request, document_id):
|
|
document = get_object_or_404(CircleDocument, id=document_id)
|
|
if not is_circle_expert(
|
|
request.user, document.learning_sequence_id, document.course_session_id
|
|
):
|
|
raise PermissionDenied()
|
|
|
|
document.delete()
|
|
|
|
return Response(status=200)
|