-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
44 changed files
with
1,337 additions
and
1,541 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
""" URL patterns for the Turnitin API.""" | ||
|
||
from django.urls import include, path | ||
|
||
app_name = "platform_plugin_turnitin" | ||
|
||
urlpatterns = [ | ||
path( | ||
"v1/", | ||
include("platform_plugin_turnitin.api.v1.urls", namespace="turnitin-api-v1"), | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
"""Utility functions for the Turnitin API.""" | ||
|
||
from typing import Optional, Tuple | ||
|
||
from opaque_keys import InvalidKeyError | ||
from opaque_keys.edx.keys import CourseKey | ||
from rest_framework import status | ||
from rest_framework.response import Response | ||
|
||
from platform_plugin_turnitin.edxapp_wrapper import CourseInstructorRole, CourseStaffRole, get_course_overview_or_none | ||
|
||
|
||
def get_fullname(name: str) -> Tuple[str, str]: | ||
""" | ||
Returns the first and last name from a full name. | ||
Args: | ||
name (str): Full name. | ||
Returns: | ||
Tuple[str, str]: First and last name. | ||
""" | ||
first_name, last_name = "", "" | ||
|
||
if name: | ||
fullname = name.split(" ", 1) | ||
first_name = fullname[0] | ||
|
||
if fullname[1:]: | ||
last_name = fullname[1] | ||
|
||
return first_name, last_name | ||
|
||
|
||
def api_field_errors(field_errors: dict, status_code: int) -> Response: | ||
""" | ||
Build a response with field errors. | ||
Args: | ||
field_errors (dict): Errors to return. | ||
status_code (int): Status code to return. | ||
Returns: | ||
Response: Response with field errors. | ||
""" | ||
return Response(data={"field_errors": field_errors}, status=status_code) | ||
|
||
|
||
def api_error(error: str, status_code: int) -> Response: | ||
""" | ||
Build a response with an error. | ||
Args: | ||
error (str): Error to return. | ||
status_code (int): Status code to return. | ||
Returns: | ||
Response: Response with an error. | ||
""" | ||
return Response(data={"error": error}, status=status_code) | ||
|
||
|
||
def validate_request( | ||
request, course_id: str, only_course: bool = False | ||
) -> Optional[Response]: | ||
""" | ||
Validate the request and return a error response if the request is invalid. | ||
Error responses are returned if: | ||
- The course ID is invalid. | ||
- The course is not found. | ||
- The user does not have access to generate credentials. | ||
Args: | ||
request (Request): The request object. | ||
course_id (str): The course ID. | ||
only_course (bool, optional): If True, only validate the course ID. Defaults to False. | ||
Returns: | ||
Optional[Response]: A response object if the request is invalid. | ||
""" | ||
try: | ||
course_key = CourseKey.from_string(course_id) | ||
except InvalidKeyError: | ||
return api_field_errors( | ||
{"course_id": f"The supplied {course_id=} key is not valid."}, | ||
status_code=status.HTTP_400_BAD_REQUEST, | ||
) | ||
|
||
course_overview = get_course_overview_or_none(course_id) | ||
|
||
if course_overview is None: | ||
return api_field_errors( | ||
{"course_id": f"The course with {course_id=} is not found."}, | ||
status_code=status.HTTP_404_NOT_FOUND, | ||
) | ||
|
||
if only_course: | ||
return None | ||
|
||
user_has_access = any( | ||
[ | ||
request.user.is_staff, | ||
CourseStaffRole(course_key).has_user(request.user), | ||
CourseInstructorRole(course_key).has_user(request.user), | ||
] | ||
) | ||
|
||
if not user_has_access: | ||
return api_error( | ||
"The user does not have access to generate credentials.", | ||
status_code=status.HTTP_403_FORBIDDEN, | ||
) | ||
|
||
return None |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
"""URL patterns for the Turnitin API""" | ||
|
||
from django.urls import path | ||
|
||
from platform_plugin_turnitin.api.v1 import views | ||
|
||
app_name = "platform_plugin_turnitin" | ||
|
||
urlpatterns = [ | ||
path("upload-file/", views.TurnitinUploadFileAPIView.as_view(), name="upload-file"), | ||
path( | ||
"submission/<uuid:submission_id>/", | ||
views.TurnitinSubmissionAPIView.as_view(), | ||
name="get-submission", | ||
), | ||
path( | ||
"similarity-report/<uuid:submission_id>/", | ||
views.TurnitinSimilarityReportAPIView.as_view(), | ||
name="generate-similarity-report", | ||
), | ||
path( | ||
"similarity-report/<uuid:submission_id>/", | ||
views.TurnitinSimilarityReportAPIView.as_view(), | ||
name="get-similarity-report", | ||
), | ||
path( | ||
"viewer-url/<uuid:submission_id>/", | ||
views.TurnitinViewerAPIView.as_view(), | ||
name="viewer-url", | ||
), | ||
] |
Oops, something went wrong.