Merge branch 'master' into rg/feat/FC0031/add_bearer_authorization_in_delete_user_api
This commit is contained in:
@@ -13,3 +13,7 @@ from .proctoring import (
|
||||
ProctoringErrorsSerializer
|
||||
)
|
||||
from .settings import CourseSettingsSerializer
|
||||
from .xblock import XblockSerializer
|
||||
from .videos import VideoUploadSerializer, VideoImageSerializer
|
||||
from .transcripts import TranscriptSerializer
|
||||
from .assets import AssetSerializer
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
"""
|
||||
API Serializers for assets
|
||||
"""
|
||||
from rest_framework import serializers
|
||||
from .common import StrictSerializer
|
||||
|
||||
|
||||
class AssetSerializer(StrictSerializer):
|
||||
"""
|
||||
Strict Serializer for file assets.
|
||||
"""
|
||||
file = serializers.FileField(required=False, allow_null=True)
|
||||
locked = serializers.BooleanField(required=False, allow_null=True)
|
||||
@@ -17,3 +17,36 @@ class CourseCommonSerializer(serializers.Serializer):
|
||||
rerun_link = serializers.CharField()
|
||||
run = serializers.CharField()
|
||||
url = serializers.CharField()
|
||||
|
||||
|
||||
class StrictSerializer(serializers.Serializer):
|
||||
"""
|
||||
Serializers that validates strong parameters, i.e. that no extra fields are passed in.
|
||||
The serializer inheriting from this may throw a ValidationError and can be called in a try/catch
|
||||
block that will return a 400 response on ValidationError.
|
||||
"""
|
||||
def to_internal_value(self, data):
|
||||
"""
|
||||
raise validation error if there are any unexpected fields.
|
||||
"""
|
||||
# Transform and validate the expected fields
|
||||
ret = super().to_internal_value(data)
|
||||
|
||||
# Get the list of valid fields from the serializer
|
||||
valid_fields = set(self.fields.keys())
|
||||
|
||||
# Check for unexpected fields
|
||||
extra_fields = set(data.keys()) - valid_fields
|
||||
if extra_fields:
|
||||
# Check if these unexpected fields are due to nested serializers
|
||||
for field_name in list(extra_fields):
|
||||
if isinstance(self.fields.get(field_name), serializers.BaseSerializer):
|
||||
extra_fields.remove(field_name)
|
||||
|
||||
# If there are still unexpected fields left, raise an error
|
||||
if extra_fields:
|
||||
raise serializers.ValidationError(
|
||||
{field: ["This field is not expected."] for field in extra_fields}
|
||||
)
|
||||
|
||||
return ret
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
"""
|
||||
API Serializers for transcripts
|
||||
"""
|
||||
from rest_framework import serializers
|
||||
from .common import StrictSerializer
|
||||
|
||||
|
||||
class TranscriptSerializer(StrictSerializer):
|
||||
"""
|
||||
Strict Serializer for video transcripts.
|
||||
"""
|
||||
file = serializers.FileField()
|
||||
edx_video_id = serializers.CharField()
|
||||
language_code = serializers.CharField(required=False, allow_null=True)
|
||||
new_language_code = serializers.CharField(required=False, allow_null=True)
|
||||
@@ -0,0 +1,29 @@
|
||||
"""
|
||||
API Serializers for videos
|
||||
"""
|
||||
from rest_framework import serializers
|
||||
from .common import StrictSerializer
|
||||
|
||||
|
||||
class FileSpecSerializer(StrictSerializer):
|
||||
""" Strict Serializer for file specs """
|
||||
file_name = serializers.CharField()
|
||||
content_type = serializers.ChoiceField(choices=['video/mp4', 'video/webm', 'video/ogg'])
|
||||
|
||||
|
||||
class VideoUploadSerializer(StrictSerializer):
|
||||
"""
|
||||
Strict Serializer for video upload urls.
|
||||
Note that these are not actually video uploads but endpoints to generate an upload url for AWS
|
||||
and generating a video placeholder without performing an actual upload.
|
||||
"""
|
||||
files = serializers.ListField(
|
||||
child=FileSpecSerializer()
|
||||
)
|
||||
|
||||
|
||||
class VideoImageSerializer(StrictSerializer):
|
||||
"""
|
||||
Strict Serializer for video imgage files.
|
||||
"""
|
||||
file = serializers.ImageField()
|
||||
@@ -1,15 +1,79 @@
|
||||
"""
|
||||
API Serializers for xblocks
|
||||
"""
|
||||
from rest_framework import serializers
|
||||
from .common import StrictSerializer
|
||||
|
||||
# The XblockSerializer is designed to be scalable and generic. As such, its structure
|
||||
# should remain as general as possible. Avoid indiscriminately adding fields to it,
|
||||
# especially those that are xblock-specific. In the future, we aim to develop a solution
|
||||
# that can generate serializer fields dynamically based on the xblock definitions.
|
||||
|
||||
|
||||
# TODO: implement and use serializer
|
||||
# from rest_framework import serializers
|
||||
class XblockSerializer(StrictSerializer):
|
||||
"""
|
||||
A serializer for xblocks that enforces strict validation.
|
||||
|
||||
# class XblockSerializer(serializers.Serializer):
|
||||
# """Serializer for xblocks"""
|
||||
# id=serializers.CharField(required=False)
|
||||
# display_name=serializers.CharField(required=False)
|
||||
# category=serializers.CharField(required=False)
|
||||
# data=serializers.CharField(required=False)
|
||||
# metadata=serializers.DictField(required=False)
|
||||
The serializer ensures:
|
||||
1. All top-level fields have the expected data types.
|
||||
2. No unexpected fields are passed in.
|
||||
|
||||
Note: The current list of fields is not exhaustive. It is primarily designed
|
||||
to support the CMS API demo. While optional fields have been added, they were
|
||||
chosen based on ease of discovery, not comprehensiveness.
|
||||
"""
|
||||
id = serializers.CharField(required=False, allow_null=True)
|
||||
parent_locator = serializers.CharField(required=False, allow_null=True)
|
||||
display_name = serializers.CharField(required=False, allow_null=True)
|
||||
category = serializers.CharField(required=False, allow_null=True)
|
||||
data = serializers.CharField(required=False, allow_null=True)
|
||||
metadata = serializers.DictField(required=False, allow_null=True)
|
||||
has_changes = serializers.BooleanField(required=False, allow_null=True)
|
||||
children = serializers.ListField(required=False, allow_null=True)
|
||||
fields = serializers.DictField(required=False, allow_null=True)
|
||||
has_children = serializers.BooleanField(required=False, allow_null=True)
|
||||
video_sharing_enabled = serializers.BooleanField(required=False, allow_null=True)
|
||||
video_sharing_options = serializers.CharField(required=False, allow_null=True)
|
||||
video_sharing_doc_url = serializers.CharField(required=False, allow_null=True)
|
||||
edited_on = serializers.CharField(required=False, allow_null=True)
|
||||
published = serializers.BooleanField(required=False, allow_null=True)
|
||||
published_on = serializers.JSONField(required=False, allow_null=True)
|
||||
studio_url = serializers.CharField(required=False, allow_null=True)
|
||||
released_to_students = serializers.BooleanField(required=False, allow_null=True)
|
||||
release_date = serializers.JSONField(required=False, allow_null=True)
|
||||
nullout = serializers.JSONField(required=False, allow_null=True)
|
||||
graderType = serializers.JSONField(required=False, allow_null=True)
|
||||
visibility_state = serializers.CharField(required=False, allow_null=True)
|
||||
has_explicit_staff_lock = serializers.BooleanField(
|
||||
required=False, allow_null=True
|
||||
)
|
||||
start = serializers.CharField(required=False, allow_null=True)
|
||||
graded = serializers.BooleanField(required=False, allow_null=True)
|
||||
due_date = serializers.CharField(required=False, allow_null=True)
|
||||
due = serializers.JSONField(required=False, allow_null=True)
|
||||
relative_weeks_due = serializers.JSONField(required=False, allow_null=True)
|
||||
format = serializers.JSONField(required=False, allow_null=True)
|
||||
course_graders = serializers.ListField(required=False, allow_null=True)
|
||||
actions = serializers.DictField(required=False, allow_null=True)
|
||||
explanatory_message = serializers.Field(required=False, allow_null=True)
|
||||
group_access = serializers.DictField(required=False, allow_null=True)
|
||||
user_partitions = serializers.ListField(required=False, allow_null=True)
|
||||
show_correctness = serializers.CharField(required=False, allow_null=True)
|
||||
discussion_enabled = serializers.BooleanField(required=False, allow_null=True)
|
||||
ancestor_has_staff_lock = serializers.BooleanField(required=False, allow_null=True)
|
||||
user_partition_info = serializers.DictField(required=False, allow_null=True)
|
||||
summary_configuration_enabled = serializers.JSONField(required=False, allow_null=True)
|
||||
isPrereq = serializers.BooleanField(required=False, allow_null=True)
|
||||
prereqUsageKey = serializers.CharField(required=False, allow_null=True)
|
||||
prereqMinScore = serializers.IntegerField(required=False, allow_null=True)
|
||||
prereqMinCompletion = serializers.IntegerField(required=False, allow_null=True)
|
||||
publish = serializers.ChoiceField(
|
||||
required=False,
|
||||
allow_null=True,
|
||||
choices=['make_public', 'republish', 'discard_changes']
|
||||
)
|
||||
duplicate_source_locator = serializers.CharField(required=False, allow_null=True)
|
||||
move_source_locator = serializers.CharField(required=False, allow_null=True)
|
||||
target_index = serializers.IntegerField(required=False, allow_null=True)
|
||||
boilerplate = serializers.JSONField(required=False, allow_null=True)
|
||||
staged_content = serializers.CharField(required=False, allow_null=True)
|
||||
|
||||
@@ -74,7 +74,7 @@ urlpatterns = [
|
||||
videos.VideosView.as_view(), name='studio_content_videos_uploads'
|
||||
),
|
||||
re_path(
|
||||
fr'^videos/images/{settings.COURSE_ID_PATTERN}/{VIDEO_ID_PATTERN}?$',
|
||||
fr'^videos/images/{settings.COURSE_ID_PATTERN}/{VIDEO_ID_PATTERN}$',
|
||||
videos.VideoImagesView.as_view(), name='studio_content_videos_images'
|
||||
),
|
||||
re_path(
|
||||
|
||||
@@ -14,6 +14,11 @@ from ....api import course_author_access_required
|
||||
from cms.djangoapps.contentstore.asset_storage_handlers import handle_assets
|
||||
import cms.djangoapps.contentstore.toggles as contentstore_toggles
|
||||
|
||||
from cms.djangoapps.contentstore.rest_api.v1.serializers import AssetSerializer
|
||||
from .utils import validate_request_with_serializer
|
||||
from rest_framework.parsers import (MultiPartParser, FormParser, JSONParser)
|
||||
from openedx.core.lib.api.parsers import TypedFileUploadParser
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
toggles = contentstore_toggles
|
||||
|
||||
@@ -25,6 +30,8 @@ class AssetsView(DeveloperErrorViewMixin, RetrieveUpdateDestroyAPIView, CreateAP
|
||||
course_key: required argument, needed to authorize course authors and identify the asset.
|
||||
asset_key_string: required argument, needed to identify the asset.
|
||||
"""
|
||||
serializer_class = AssetSerializer
|
||||
parser_classes = (JSONParser, MultiPartParser, FormParser, TypedFileUploadParser)
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
# TODO: probably want to refactor this to a decorator.
|
||||
@@ -44,11 +51,13 @@ class AssetsView(DeveloperErrorViewMixin, RetrieveUpdateDestroyAPIView, CreateAP
|
||||
|
||||
@csrf_exempt
|
||||
@course_author_access_required
|
||||
@validate_request_with_serializer
|
||||
def create(self, request, course_key): # pylint: disable=arguments-differ
|
||||
return handle_assets(request, course_key.html_id())
|
||||
|
||||
@course_author_access_required
|
||||
@expect_json_in_class_view
|
||||
@validate_request_with_serializer
|
||||
def update(self, request, course_key, asset_key_string): # pylint: disable=arguments-differ
|
||||
return handle_assets(request, course_key.html_id(), asset_key_string)
|
||||
|
||||
|
||||
@@ -6,9 +6,11 @@ not the underlying Xblock service.
|
||||
It checks that the assets_handler method of the Xblock service is called with the expected parameters.
|
||||
"""
|
||||
from unittest.mock import patch
|
||||
from django.core.files import File
|
||||
from django.http import JsonResponse
|
||||
|
||||
from django.urls import reverse
|
||||
from mock import MagicMock
|
||||
from rest_framework import status
|
||||
from rest_framework.test import APITestCase
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
||||
@@ -17,6 +19,8 @@ from cms.djangoapps.contentstore.tests.test_utils import AuthorizeStaffTestCase
|
||||
|
||||
|
||||
ASSET_KEY_STRING = "asset-v1:dede+aba+weagi+type@asset+block@_0e37192a-42c4-441e-a3e1-8e40ec304e2e.jpg"
|
||||
mock_image = MagicMock(file=File)
|
||||
mock_image.name = "test.jpg"
|
||||
|
||||
|
||||
class AssetsViewTestCase(AuthorizeStaffTestCase):
|
||||
@@ -146,7 +150,7 @@ class AssetsViewPostTest(AssetsViewTestCase, ModuleStoreTestCase, APITestCase):
|
||||
|
||||
def get_test_data(self):
|
||||
return {
|
||||
"file": ASSET_KEY_STRING,
|
||||
"file": mock_image,
|
||||
}
|
||||
|
||||
def assert_assets_handler_called(self, *, mock_handle_assets, response):
|
||||
@@ -159,7 +163,7 @@ class AssetsViewPostTest(AssetsViewTestCase, ModuleStoreTestCase, APITestCase):
|
||||
|
||||
course_id = self.get_course_key_string()
|
||||
|
||||
assert passed_args.data.get("file") == ASSET_KEY_STRING
|
||||
assert passed_args.data.get("file").name == mock_image.name
|
||||
assert passed_args.method == "POST"
|
||||
assert passed_args.path == self.get_url()
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ class XBlockViewTestCase(AuthorizeStaffTestCase):
|
||||
return_value=JsonResponse(
|
||||
{
|
||||
"locator": TEST_LOCATOR,
|
||||
"courseKey": AuthorizeStaffTestCase.get_course_key_string(),
|
||||
"course_key": AuthorizeStaffTestCase.get_course_key_string(),
|
||||
}
|
||||
),
|
||||
)
|
||||
@@ -128,7 +128,6 @@ class XBlockViewGetTest(XBlockViewTestCase, ModuleStoreTestCase, APITestCase):
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
data = response.json()
|
||||
assert data["locator"] == TEST_LOCATOR
|
||||
assert data["courseKey"] == self.get_course_key_string()
|
||||
|
||||
|
||||
class XBlockViewPostTest(XBlockViewTestCase, ModuleStoreTestCase, APITestCase):
|
||||
@@ -150,7 +149,6 @@ class XBlockViewPostTest(XBlockViewTestCase, ModuleStoreTestCase, APITestCase):
|
||||
return {
|
||||
"parent_locator": course_id,
|
||||
"category": "html",
|
||||
"courseKey": course_id,
|
||||
}
|
||||
|
||||
def assert_xblock_handler_called(self, *, mock_handle_xblock, response):
|
||||
@@ -161,9 +159,6 @@ class XBlockViewPostTest(XBlockViewTestCase, ModuleStoreTestCase, APITestCase):
|
||||
mock_handle_xblock.assert_called_once()
|
||||
passed_args = mock_handle_xblock.call_args[0][0]
|
||||
|
||||
course_id = self.get_course_key_string()
|
||||
|
||||
assert passed_args.data.get("courseKey") == course_id
|
||||
assert passed_args.method == "POST"
|
||||
assert passed_args.path == self.get_url()
|
||||
|
||||
@@ -187,7 +182,6 @@ class XBlockViewPostTest(XBlockViewTestCase, ModuleStoreTestCase, APITestCase):
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
data = response.json()
|
||||
assert data["locator"] == TEST_LOCATOR
|
||||
assert data["courseKey"] == self.get_course_key_string()
|
||||
|
||||
|
||||
class XBlockViewPutTest(XBlockViewTestCase, ModuleStoreTestCase, APITestCase):
|
||||
@@ -196,10 +190,8 @@ class XBlockViewPutTest(XBlockViewTestCase, ModuleStoreTestCase, APITestCase):
|
||||
"""
|
||||
|
||||
def get_test_data(self):
|
||||
course_id = self.get_course_key_string()
|
||||
return {
|
||||
"category": "html",
|
||||
"courseKey": course_id,
|
||||
"data": "<p>Updated block!</p>",
|
||||
"has_changes": True,
|
||||
"id": TEST_LOCATOR,
|
||||
@@ -216,9 +208,6 @@ class XBlockViewPutTest(XBlockViewTestCase, ModuleStoreTestCase, APITestCase):
|
||||
mock_handle_xblock.assert_called_once()
|
||||
passed_args = mock_handle_xblock.call_args[0][0]
|
||||
|
||||
course_id = self.get_course_key_string()
|
||||
|
||||
assert passed_args.data.get("courseKey") == course_id
|
||||
assert passed_args.data.get("data") == "<p>Updated block!</p>"
|
||||
assert passed_args.data.get("id") == TEST_LOCATOR
|
||||
assert passed_args.method == "PUT"
|
||||
@@ -244,7 +233,6 @@ class XBlockViewPutTest(XBlockViewTestCase, ModuleStoreTestCase, APITestCase):
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
data = response.json()
|
||||
assert data["locator"] == TEST_LOCATOR
|
||||
assert data["courseKey"] == self.get_course_key_string()
|
||||
|
||||
|
||||
class XBlockViewPatchTest(XBlockViewTestCase, ModuleStoreTestCase, APITestCase):
|
||||
@@ -253,10 +241,8 @@ class XBlockViewPatchTest(XBlockViewTestCase, ModuleStoreTestCase, APITestCase):
|
||||
"""
|
||||
|
||||
def get_test_data(self):
|
||||
course_id = self.get_course_key_string()
|
||||
return {
|
||||
"category": "html",
|
||||
"courseKey": course_id,
|
||||
"data": "<p>Patched block!</p>",
|
||||
"has_changes": True,
|
||||
"id": TEST_LOCATOR,
|
||||
@@ -273,9 +259,6 @@ class XBlockViewPatchTest(XBlockViewTestCase, ModuleStoreTestCase, APITestCase):
|
||||
mock_handle_xblock.assert_called_once()
|
||||
passed_args = mock_handle_xblock.call_args[0][0]
|
||||
|
||||
course_id = self.get_course_key_string()
|
||||
|
||||
assert passed_args.data.get("courseKey") == course_id
|
||||
assert passed_args.data.get("data") == "<p>Patched block!</p>"
|
||||
assert passed_args.data.get("id") == TEST_LOCATOR
|
||||
assert passed_args.method == "PATCH"
|
||||
@@ -301,7 +284,6 @@ class XBlockViewPatchTest(XBlockViewTestCase, ModuleStoreTestCase, APITestCase):
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
data = response.json()
|
||||
assert data["locator"] == TEST_LOCATOR
|
||||
assert data["courseKey"] == self.get_course_key_string()
|
||||
|
||||
|
||||
class XBlockViewDeleteTest(XBlockViewTestCase, ModuleStoreTestCase, APITestCase):
|
||||
@@ -343,4 +325,3 @@ class XBlockViewDeleteTest(XBlockViewTestCase, ModuleStoreTestCase, APITestCase)
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
data = response.json()
|
||||
assert data["locator"] == TEST_LOCATOR
|
||||
assert data["courseKey"] == self.get_course_key_string()
|
||||
|
||||
@@ -21,6 +21,11 @@ from cms.djangoapps.contentstore.transcript_storage_handlers import (
|
||||
handle_transcript_download,
|
||||
)
|
||||
import cms.djangoapps.contentstore.toggles as contentstore_toggles
|
||||
from cms.djangoapps.contentstore.rest_api.v1.serializers import TranscriptSerializer
|
||||
from rest_framework.parsers import (MultiPartParser, FormParser)
|
||||
from openedx.core.lib.api.parsers import TypedFileUploadParser
|
||||
|
||||
from .utils import validate_request_with_serializer
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
toggles = contentstore_toggles
|
||||
@@ -34,6 +39,8 @@ class TranscriptView(DeveloperErrorViewMixin, CreateAPIView, RetrieveAPIView, De
|
||||
edx_video_id: optional query parameter, needed to identify the transcript.
|
||||
language_code: optional query parameter, needed to identify the transcript.
|
||||
"""
|
||||
serializer_class = TranscriptSerializer
|
||||
parser_classes = (MultiPartParser, FormParser, TypedFileUploadParser)
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
if not toggles.use_studio_content_api():
|
||||
@@ -43,6 +50,7 @@ class TranscriptView(DeveloperErrorViewMixin, CreateAPIView, RetrieveAPIView, De
|
||||
@csrf_exempt
|
||||
@course_author_access_required
|
||||
@expect_json_in_class_view
|
||||
@validate_request_with_serializer
|
||||
def create(self, request, course_key_string): # pylint: disable=arguments-differ
|
||||
return upload_transcript(request)
|
||||
|
||||
|
||||
23
cms/djangoapps/contentstore/rest_api/v1/views/utils.py
Normal file
23
cms/djangoapps/contentstore/rest_api/v1/views/utils.py
Normal file
@@ -0,0 +1,23 @@
|
||||
"""
|
||||
Utilities for the REST API views.
|
||||
"""
|
||||
from functools import wraps
|
||||
from django.http import HttpResponseBadRequest
|
||||
|
||||
|
||||
def validate_request_with_serializer(view_func):
|
||||
"""
|
||||
A decorator to validate request data using the view's serializer.
|
||||
|
||||
Usage:
|
||||
@validate_request_with_serializer
|
||||
def my_view_function(self, request, ...):
|
||||
...
|
||||
"""
|
||||
@wraps(view_func)
|
||||
def _wrapped_view(instance, request, *args, **kwargs):
|
||||
serializer = instance.serializer_class(data=request.data)
|
||||
if not serializer.is_valid():
|
||||
return HttpResponseBadRequest(reason=serializer.errors)
|
||||
return view_func(instance, request, *args, **kwargs)
|
||||
return _wrapped_view
|
||||
@@ -7,10 +7,12 @@ from rest_framework.generics import (
|
||||
RetrieveAPIView,
|
||||
DestroyAPIView
|
||||
)
|
||||
from rest_framework.parsers import (MultiPartParser, FormParser)
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from django.http import Http404
|
||||
|
||||
from openedx.core.lib.api.view_utils import DeveloperErrorViewMixin, view_auth_classes
|
||||
from openedx.core.lib.api.parsers import TypedFileUploadParser
|
||||
from common.djangoapps.util.json_request import expect_json_in_class_view
|
||||
|
||||
from ....api import course_author_access_required
|
||||
@@ -19,10 +21,12 @@ from cms.djangoapps.contentstore.video_storage_handlers import (
|
||||
handle_videos,
|
||||
get_video_encodings_download,
|
||||
handle_video_images,
|
||||
enabled_video_features,
|
||||
handle_generate_video_upload_link
|
||||
enabled_video_features
|
||||
)
|
||||
from cms.djangoapps.contentstore.rest_api.v1.serializers import VideoUploadSerializer, VideoImageSerializer
|
||||
import cms.djangoapps.contentstore.toggles as contentstore_toggles
|
||||
from .utils import validate_request_with_serializer
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
toggles = contentstore_toggles
|
||||
@@ -35,6 +39,7 @@ class VideosView(DeveloperErrorViewMixin, CreateAPIView, RetrieveAPIView, Destro
|
||||
course_key: required argument, needed to authorize course authors and identify the video.
|
||||
video_id: required argument, needed to identify the video.
|
||||
"""
|
||||
serializer_class = VideoUploadSerializer
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
# TODO: probably want to refactor this to a decorator.
|
||||
@@ -50,7 +55,9 @@ class VideosView(DeveloperErrorViewMixin, CreateAPIView, RetrieveAPIView, Destro
|
||||
@csrf_exempt
|
||||
@course_author_access_required
|
||||
@expect_json_in_class_view
|
||||
@validate_request_with_serializer
|
||||
def create(self, request, course_key): # pylint: disable=arguments-differ
|
||||
"""Deprecated. Use the upload_link endpoint instead."""
|
||||
return handle_videos(request, course_key.html_id())
|
||||
|
||||
@course_author_access_required
|
||||
@@ -70,6 +77,8 @@ class VideoImagesView(DeveloperErrorViewMixin, CreateAPIView):
|
||||
course_key: required argument, needed to authorize course authors and identify the video.
|
||||
video_id: required argument, needed to identify the video.
|
||||
"""
|
||||
serializer_class = VideoImageSerializer
|
||||
parser_classes = (MultiPartParser, FormParser, TypedFileUploadParser)
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
# TODO: probably want to refactor this to a decorator.
|
||||
@@ -85,6 +94,7 @@ class VideoImagesView(DeveloperErrorViewMixin, CreateAPIView):
|
||||
@csrf_exempt
|
||||
@course_author_access_required
|
||||
@expect_json_in_class_view
|
||||
@validate_request_with_serializer
|
||||
def create(self, request, course_key, edx_video_id=None): # pylint: disable=arguments-differ
|
||||
return handle_video_images(request, course_key.html_id(), edx_video_id)
|
||||
|
||||
@@ -140,6 +150,7 @@ class UploadLinkView(DeveloperErrorViewMixin, CreateAPIView):
|
||||
"""
|
||||
public rest API endpoint providing a list of enabled video features.
|
||||
"""
|
||||
serializer_class = VideoUploadSerializer
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
# TODO: probably want to refactor this to a decorator.
|
||||
@@ -155,5 +166,6 @@ class UploadLinkView(DeveloperErrorViewMixin, CreateAPIView):
|
||||
@csrf_exempt
|
||||
@course_author_access_required
|
||||
@expect_json_in_class_view
|
||||
@validate_request_with_serializer
|
||||
def create(self, request, course_key): # pylint: disable=arguments-differ
|
||||
return handle_generate_video_upload_link(request, course_key.html_id())
|
||||
return handle_videos(request, course_key.html_id())
|
||||
|
||||
@@ -13,7 +13,8 @@ from cms.djangoapps.contentstore.api import course_author_access_required
|
||||
from cms.djangoapps.contentstore.xblock_storage_handlers import view_handlers
|
||||
import cms.djangoapps.contentstore.toggles as contentstore_toggles
|
||||
|
||||
# from cms.djangoapps.contentstore.rest_api.v1.serializers import XblockSerializer
|
||||
from cms.djangoapps.contentstore.rest_api.v1.serializers import XblockSerializer
|
||||
from .utils import validate_request_with_serializer
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@@ -29,8 +30,7 @@ class XblockView(DeveloperErrorViewMixin, RetrieveUpdateDestroyAPIView, CreateAP
|
||||
usage_key_string (optional):
|
||||
xblock identifier, for example in the form of "block-v1:<course id>+type@<type>+block@<block id>"
|
||||
"""
|
||||
# TODO: uncomment next line after XblockSerializer is implemented
|
||||
# serializer_class = XblockSerializer
|
||||
serializer_class = XblockSerializer
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
# TODO: probably want to refactor this to a decorator.
|
||||
@@ -51,11 +51,13 @@ class XblockView(DeveloperErrorViewMixin, RetrieveUpdateDestroyAPIView, CreateAP
|
||||
|
||||
@course_author_access_required
|
||||
@expect_json_in_class_view
|
||||
@validate_request_with_serializer
|
||||
def update(self, request, course_key, usage_key_string=None):
|
||||
return handle_xblock(request, usage_key_string)
|
||||
|
||||
@course_author_access_required
|
||||
@expect_json_in_class_view
|
||||
@validate_request_with_serializer
|
||||
def partial_update(self, request, course_key, usage_key_string=None):
|
||||
return handle_xblock(request, usage_key_string)
|
||||
|
||||
@@ -67,5 +69,6 @@ class XblockView(DeveloperErrorViewMixin, RetrieveUpdateDestroyAPIView, CreateAP
|
||||
@csrf_exempt
|
||||
@course_author_access_required
|
||||
@expect_json_in_class_view
|
||||
@validate_request_with_serializer
|
||||
def create(self, request, course_key, usage_key_string=None):
|
||||
return handle_xblock(request, usage_key_string)
|
||||
|
||||
@@ -5,7 +5,7 @@ Unit tests for video utils.
|
||||
|
||||
from datetime import datetime
|
||||
from unittest import TestCase
|
||||
from unittest.mock import MagicMock, patch
|
||||
from unittest import mock
|
||||
|
||||
import ddt
|
||||
import pytz
|
||||
@@ -144,7 +144,7 @@ class ScrapeVideoThumbnailsTestCase(CourseTestCase):
|
||||
return mocked_response
|
||||
|
||||
@override_settings(AWS_ACCESS_KEY_ID='test_key_id', AWS_SECRET_ACCESS_KEY='test_secret')
|
||||
@patch('requests.get')
|
||||
@mock.patch('requests.get')
|
||||
@ddt.data(
|
||||
(
|
||||
{
|
||||
@@ -228,7 +228,7 @@ class ScrapeVideoThumbnailsTestCase(CourseTestCase):
|
||||
self.assertEqual(thumbnail_content_type, 'image/jpeg')
|
||||
|
||||
@override_settings(AWS_ACCESS_KEY_ID='test_key_id', AWS_SECRET_ACCESS_KEY='test_secret')
|
||||
@patch('requests.get')
|
||||
@mock.patch('requests.get')
|
||||
def test_scrape_youtube_thumbnail(self, mocked_request):
|
||||
"""
|
||||
Test that youtube thumbnails are correctly scrapped.
|
||||
@@ -273,8 +273,8 @@ class ScrapeVideoThumbnailsTestCase(CourseTestCase):
|
||||
)
|
||||
)
|
||||
@override_settings(AWS_ACCESS_KEY_ID='test_key_id', AWS_SECRET_ACCESS_KEY='test_secret')
|
||||
@patch('cms.djangoapps.contentstore.video_utils.LOGGER')
|
||||
@patch('requests.get')
|
||||
@mock.patch('cms.djangoapps.contentstore.video_utils.LOGGER')
|
||||
@mock.patch('requests.get')
|
||||
@ddt.unpack
|
||||
def test_scrape_youtube_thumbnail_logging(
|
||||
self,
|
||||
@@ -333,8 +333,8 @@ class ScrapeVideoThumbnailsTestCase(CourseTestCase):
|
||||
)
|
||||
),
|
||||
)
|
||||
@patch('cms.djangoapps.contentstore.video_utils.LOGGER')
|
||||
@patch('cms.djangoapps.contentstore.video_utils.download_youtube_video_thumbnail')
|
||||
@mock.patch('cms.djangoapps.contentstore.video_utils.LOGGER')
|
||||
@mock.patch('cms.djangoapps.contentstore.video_utils.download_youtube_video_thumbnail')
|
||||
@ddt.unpack
|
||||
def test_no_video_thumbnail_downloaded(
|
||||
self,
|
||||
@@ -376,7 +376,7 @@ class S3Boto3TestCase(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.storage = S3Boto3Storage()
|
||||
self.storage._connections.connection = MagicMock() # pylint: disable=protected-access
|
||||
self.storage._connections.connection = mock.MagicMock() # pylint: disable=protected-access
|
||||
|
||||
def order_dict(self, dictionary):
|
||||
"""
|
||||
@@ -417,18 +417,18 @@ class S3Boto3TestCase(TestCase):
|
||||
content = ContentFile('new content')
|
||||
|
||||
storage = S3Boto3Storage(**{'bucket_name': 'test'})
|
||||
storage._connections.connection = MagicMock() # pylint: disable=protected-access
|
||||
storage._connections.connection = mock.MagicMock() # pylint: disable=protected-access
|
||||
|
||||
storage.save(name, content)
|
||||
storage.bucket.Object.assert_called_once_with(name)
|
||||
|
||||
obj = storage.bucket.Object.return_value
|
||||
obj.upload_fileobj.assert_called_with(
|
||||
content,
|
||||
mock.ANY,
|
||||
ExtraArgs=self.order_dict({
|
||||
'ContentType': 'text/plain',
|
||||
}),
|
||||
Config=storage._transfer_config # pylint: disable=protected-access
|
||||
Config=storage.transfer_config # pylint: disable=protected-access
|
||||
)
|
||||
|
||||
@override_settings(AWS_DEFAULT_ACL='public-read')
|
||||
@@ -445,7 +445,7 @@ class S3Boto3TestCase(TestCase):
|
||||
name = 'test_storage_save.txt'
|
||||
content = ContentFile('new content')
|
||||
storage = S3Boto3Storage(**{'bucket_name': 'test', 'default_acl': default_acl})
|
||||
storage._connections.connection = MagicMock() # pylint: disable=protected-access
|
||||
storage._connections.connection = mock.MagicMock() # pylint: disable=protected-access
|
||||
|
||||
storage.save(name, content)
|
||||
storage.bucket.Object.assert_called_once_with(name)
|
||||
@@ -461,9 +461,9 @@ class S3Boto3TestCase(TestCase):
|
||||
del ExtraArgs['ACL']
|
||||
|
||||
obj.upload_fileobj.assert_called_with(
|
||||
content,
|
||||
mock.ANY,
|
||||
ExtraArgs=self.order_dict(ExtraArgs),
|
||||
Config=storage._transfer_config # pylint: disable=protected-access
|
||||
Config=storage.transfer_config # pylint: disable=protected-access
|
||||
)
|
||||
|
||||
@ddt.data('public-read', 'private')
|
||||
@@ -476,16 +476,16 @@ class S3Boto3TestCase(TestCase):
|
||||
content = ContentFile('new content')
|
||||
|
||||
storage = S3Boto3Storage(**{'bucket_name': 'test', 'default_acl': None})
|
||||
storage._connections.connection = MagicMock() # pylint: disable=protected-access
|
||||
storage._connections.connection = mock.MagicMock() # pylint: disable=protected-access
|
||||
|
||||
storage.save(name, content)
|
||||
storage.bucket.Object.assert_called_once_with(name)
|
||||
|
||||
obj = storage.bucket.Object.return_value
|
||||
obj.upload_fileobj.assert_called_with(
|
||||
content,
|
||||
ExtraArgs=self.order_dict({
|
||||
mock.ANY,
|
||||
Config=storage.transfer_config, # pylint: disable=protected-access
|
||||
ExtraArgs={
|
||||
'ContentType': 'text/plain',
|
||||
}),
|
||||
Config=storage._transfer_config # pylint: disable=protected-access
|
||||
},
|
||||
)
|
||||
|
||||
@@ -729,7 +729,9 @@ def videos_post(course, request):
|
||||
"""
|
||||
|
||||
if use_mock_video_uploads():
|
||||
return {'files': [{'file_name': 'video.mp4', 'upload_url': 'http://example.com/put_video'}]}, 200
|
||||
return {'files': [{
|
||||
'file_name': 'video.mp4', 'upload_url': 'http://example.com/put_video', 'edx_video_id': '1234'
|
||||
}]}, 200
|
||||
|
||||
error = None
|
||||
data = request.json
|
||||
|
||||
@@ -67,7 +67,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 0.1a\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2023-08-27 20:43+0000\n"
|
||||
"POT-Creation-Date: 2023-09-17 20:43+0000\n"
|
||||
"PO-Revision-Date: 2019-01-20 20:43+0000\n"
|
||||
"Last-Translator: Waheed Ahmed <waheed@edx.org>, 2019\n"
|
||||
"Language-Team: Catalan (https://app.transifex.com/open-edx/teams/6205/ca/)\n"
|
||||
|
||||
@@ -98,7 +98,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 0.1a\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2023-08-27 20:43+0000\n"
|
||||
"POT-Creation-Date: 2023-09-17 20:43+0000\n"
|
||||
"PO-Revision-Date: 2019-01-20 20:43+0000\n"
|
||||
"Last-Translator: Waheed Ahmed <waheed@edx.org>, 2019\n"
|
||||
"Language-Team: Greek (https://app.transifex.com/open-edx/teams/6205/el/)\n"
|
||||
|
||||
@@ -38,8 +38,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 0.1a\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2023-09-20 12:47+0000\n"
|
||||
"PO-Revision-Date: 2023-09-20 12:47:19.650590\n"
|
||||
"POT-Creation-Date: 2023-09-24 20:36+0000\n"
|
||||
"PO-Revision-Date: 2023-09-24 20:36:20.303017\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: openedx-translation <openedx-translation@googlegroups.com>\n"
|
||||
"Language: en\n"
|
||||
@@ -6374,6 +6374,17 @@ msgstr ""
|
||||
msgid "Original usage key/ID of the thing that is in the clipboard."
|
||||
msgstr ""
|
||||
|
||||
#: openedx/core/djangoapps/content_tagging/models/base.py
|
||||
#: wiki/models/article.py
|
||||
msgid "owner"
|
||||
msgstr ""
|
||||
|
||||
#: openedx/core/djangoapps/content_tagging/models/base.py
|
||||
msgid ""
|
||||
"Organization that is related to this taxonomy.If None, then this taxonomy is"
|
||||
" related to all organizations."
|
||||
msgstr ""
|
||||
|
||||
#: openedx/core/djangoapps/cors_csrf/models.py
|
||||
msgid ""
|
||||
"List of domains that are allowed to make cross-domain requests to this site."
|
||||
@@ -8169,16 +8180,6 @@ msgid ""
|
||||
"to date."
|
||||
msgstr ""
|
||||
|
||||
#: openedx/features/content_tagging/models/base.py wiki/models/article.py
|
||||
msgid "owner"
|
||||
msgstr ""
|
||||
|
||||
#: openedx/features/content_tagging/models/base.py
|
||||
msgid ""
|
||||
"Organization that is related to this taxonomy.If None, then this taxonomy is"
|
||||
" related to all organizations."
|
||||
msgstr ""
|
||||
|
||||
#: openedx/features/content_type_gating/models.py
|
||||
#: openedx/features/course_duration_limits/models.py
|
||||
#: lms/templates/support/feature_based_enrollments.html
|
||||
|
||||
@@ -32,8 +32,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 0.1a\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2023-09-20 12:47+0000\n"
|
||||
"PO-Revision-Date: 2023-09-20 12:47:19.757119\n"
|
||||
"POT-Creation-Date: 2023-09-24 20:36+0000\n"
|
||||
"PO-Revision-Date: 2023-09-24 20:36:20.294880\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: openedx-translation <openedx-translation@googlegroups.com>\n"
|
||||
"Language: en\n"
|
||||
|
||||
Binary file not shown.
@@ -38,8 +38,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 0.1a\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2023-09-20 12:47+0000\n"
|
||||
"PO-Revision-Date: 2023-09-20 12:47:19.650590\n"
|
||||
"POT-Creation-Date: 2023-09-24 20:36+0000\n"
|
||||
"PO-Revision-Date: 2023-09-24 20:36:20.303017\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: openedx-translation <openedx-translation@googlegroups.com>\n"
|
||||
"Language: eo\n"
|
||||
@@ -8051,6 +8051,19 @@ msgstr ""
|
||||
"Örïgïnäl üsägé kéý/ÌD öf thé thïng thät ïs ïn thé çlïpßöärd. Ⱡ'σяєм ιρѕυм "
|
||||
"∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α#"
|
||||
|
||||
#: openedx/core/djangoapps/content_tagging/models/base.py
|
||||
#: wiki/models/article.py
|
||||
msgid "owner"
|
||||
msgstr "öwnér Ⱡ'σяєм ιρѕ#"
|
||||
|
||||
#: openedx/core/djangoapps/content_tagging/models/base.py
|
||||
msgid ""
|
||||
"Organization that is related to this taxonomy.If None, then this taxonomy is"
|
||||
" related to all organizations."
|
||||
msgstr ""
|
||||
"Örgänïzätïön thät ïs rélätéd tö thïs täxönömý.Ìf Nöné, thén thïs täxönömý ïs"
|
||||
" rélätéd tö äll örgänïzätïöns. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт #"
|
||||
|
||||
#: openedx/core/djangoapps/cors_csrf/models.py
|
||||
msgid ""
|
||||
"List of domains that are allowed to make cross-domain requests to this site."
|
||||
@@ -10427,18 +10440,6 @@ msgstr ""
|
||||
"Ýöü hävé süççéssfüllý shïftéd ýöür çöürsé sçhédülé änd ýöür çäléndär ïs üp "
|
||||
"tö däté. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢т#"
|
||||
|
||||
#: openedx/features/content_tagging/models/base.py wiki/models/article.py
|
||||
msgid "owner"
|
||||
msgstr "öwnér Ⱡ'σяєм ιρѕ#"
|
||||
|
||||
#: openedx/features/content_tagging/models/base.py
|
||||
msgid ""
|
||||
"Organization that is related to this taxonomy.If None, then this taxonomy is"
|
||||
" related to all organizations."
|
||||
msgstr ""
|
||||
"Örgänïzätïön thät ïs rélätéd tö thïs täxönömý.Ìf Nöné, thén thïs täxönömý ïs"
|
||||
" rélätéd tö äll örgänïzätïöns. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт #"
|
||||
|
||||
#: openedx/features/content_type_gating/models.py
|
||||
#: openedx/features/course_duration_limits/models.py
|
||||
#: lms/templates/support/feature_based_enrollments.html
|
||||
|
||||
Binary file not shown.
@@ -32,8 +32,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 0.1a\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2023-09-20 12:47+0000\n"
|
||||
"PO-Revision-Date: 2023-09-20 12:47:19.757119\n"
|
||||
"POT-Creation-Date: 2023-09-24 20:36+0000\n"
|
||||
"PO-Revision-Date: 2023-09-24 20:36:20.294880\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: openedx-translation <openedx-translation@googlegroups.com>\n"
|
||||
"Language: eo\n"
|
||||
|
||||
@@ -64,7 +64,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 0.1a\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2023-08-27 20:43+0000\n"
|
||||
"POT-Creation-Date: 2023-09-17 20:43+0000\n"
|
||||
"PO-Revision-Date: 2019-01-20 20:43+0000\n"
|
||||
"Last-Translator: Abel Camacho <abelcama@gmail.com>, 2019\n"
|
||||
"Language-Team: Basque (Spain) (https://app.transifex.com/open-edx/teams/6205/eu_ES/)\n"
|
||||
|
||||
@@ -88,7 +88,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: edx-platform\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2023-08-27 20:42+0000\n"
|
||||
"POT-Creation-Date: 2023-09-17 20:42+0000\n"
|
||||
"PO-Revision-Date: 2014-06-11 15:18+0000\n"
|
||||
"Last-Translator: SeyedMahdi Saeid <saeid@edspirit.com>, 2023\n"
|
||||
"Language-Team: Persian (Iran) (http://app.transifex.com/open-edx/edx-platform/language/fa_IR/)\n"
|
||||
|
||||
@@ -316,7 +316,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 0.1a\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2023-08-27 20:43+0000\n"
|
||||
"POT-Creation-Date: 2023-09-17 20:43+0000\n"
|
||||
"PO-Revision-Date: 2019-01-20 20:43+0000\n"
|
||||
"Last-Translator: Alexandre DS <alexandre@cleverm8.com>, 2020\n"
|
||||
"Language-Team: French (https://app.transifex.com/open-edx/teams/6205/fr/)\n"
|
||||
|
||||
@@ -106,7 +106,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 0.1a\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2023-08-27 20:43+0000\n"
|
||||
"POT-Creation-Date: 2023-09-17 20:43+0000\n"
|
||||
"PO-Revision-Date: 2019-01-20 20:43+0000\n"
|
||||
"Last-Translator: Aprisa Chrysantina <aprisa.chrysantina@gmail.com>, 2019\n"
|
||||
"Language-Team: Indonesian (https://app.transifex.com/open-edx/teams/6205/id/)\n"
|
||||
|
||||
@@ -114,7 +114,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 0.1a\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2023-08-27 20:43+0000\n"
|
||||
"POT-Creation-Date: 2023-09-17 20:43+0000\n"
|
||||
"PO-Revision-Date: 2019-01-20 20:43+0000\n"
|
||||
"Last-Translator: Waheed Ahmed <waheed@edx.org>, 2019\n"
|
||||
"Language-Team: Japanese (Japan) (https://app.transifex.com/open-edx/teams/6205/ja_JP/)\n"
|
||||
|
||||
@@ -60,7 +60,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 0.1a\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2023-08-27 20:43+0000\n"
|
||||
"POT-Creation-Date: 2023-09-17 20:43+0000\n"
|
||||
"PO-Revision-Date: 2019-01-20 20:43+0000\n"
|
||||
"Last-Translator: Waheed Ahmed <waheed@edx.org>, 2019\n"
|
||||
"Language-Team: Georgian (https://app.transifex.com/open-edx/teams/6205/ka/)\n"
|
||||
|
||||
@@ -72,7 +72,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 0.1a\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2023-08-27 20:43+0000\n"
|
||||
"POT-Creation-Date: 2023-09-17 20:43+0000\n"
|
||||
"PO-Revision-Date: 2019-01-20 20:43+0000\n"
|
||||
"Last-Translator: Waheed Ahmed <waheed@edx.org>, 2019\n"
|
||||
"Language-Team: Lithuanian (Lithuania) (https://app.transifex.com/open-edx/teams/6205/lt_LT/)\n"
|
||||
|
||||
@@ -49,7 +49,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 0.1a\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2023-08-27 20:43+0000\n"
|
||||
"POT-Creation-Date: 2023-09-17 20:43+0000\n"
|
||||
"PO-Revision-Date: 2019-01-20 20:43+0000\n"
|
||||
"Last-Translator: Waheed Ahmed <waheed@edx.org>, 2019\n"
|
||||
"Language-Team: Latvian (https://app.transifex.com/open-edx/teams/6205/lv/)\n"
|
||||
|
||||
@@ -74,7 +74,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 0.1a\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2023-08-27 20:43+0000\n"
|
||||
"POT-Creation-Date: 2023-09-17 20:43+0000\n"
|
||||
"PO-Revision-Date: 2019-01-20 20:43+0000\n"
|
||||
"Last-Translator: Waheed Ahmed <waheed@edx.org>, 2019\n"
|
||||
"Language-Team: Mongolian (https://app.transifex.com/open-edx/teams/6205/mn/)\n"
|
||||
|
||||
@@ -150,7 +150,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 0.1a\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2023-08-27 20:43+0000\n"
|
||||
"POT-Creation-Date: 2023-09-17 20:43+0000\n"
|
||||
"PO-Revision-Date: 2019-01-20 20:43+0000\n"
|
||||
"Last-Translator: Marcin Miłek, 2022\n"
|
||||
"Language-Team: Polish (https://app.transifex.com/open-edx/teams/6205/pl/)\n"
|
||||
|
||||
Binary file not shown.
@@ -38,8 +38,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 0.1a\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2023-09-20 12:47+0000\n"
|
||||
"PO-Revision-Date: 2023-09-20 12:47:19.650590\n"
|
||||
"POT-Creation-Date: 2023-09-24 20:36+0000\n"
|
||||
"PO-Revision-Date: 2023-09-24 20:36:20.303017\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: openedx-translation <openedx-translation@googlegroups.com>\n"
|
||||
"Language: rtl\n"
|
||||
@@ -7007,6 +7007,19 @@ msgstr ""
|
||||
msgid "Original usage key/ID of the thing that is in the clipboard."
|
||||
msgstr "Øɹᴉƃᴉnɐl nsɐƃǝ ʞǝʎ/ƗĐ øɟ ʇɥǝ ʇɥᴉnƃ ʇɥɐʇ ᴉs ᴉn ʇɥǝ ɔlᴉdbøɐɹd."
|
||||
|
||||
#: openedx/core/djangoapps/content_tagging/models/base.py
|
||||
#: wiki/models/article.py
|
||||
msgid "owner"
|
||||
msgstr "øʍnǝɹ"
|
||||
|
||||
#: openedx/core/djangoapps/content_tagging/models/base.py
|
||||
msgid ""
|
||||
"Organization that is related to this taxonomy.If None, then this taxonomy is"
|
||||
" related to all organizations."
|
||||
msgstr ""
|
||||
"Øɹƃɐnᴉzɐʇᴉøn ʇɥɐʇ ᴉs ɹǝlɐʇǝd ʇø ʇɥᴉs ʇɐxønøɯʎ.Ɨɟ Nønǝ, ʇɥǝn ʇɥᴉs ʇɐxønøɯʎ ᴉs"
|
||||
" ɹǝlɐʇǝd ʇø ɐll øɹƃɐnᴉzɐʇᴉøns."
|
||||
|
||||
#: openedx/core/djangoapps/cors_csrf/models.py
|
||||
msgid ""
|
||||
"List of domains that are allowed to make cross-domain requests to this site."
|
||||
@@ -9018,18 +9031,6 @@ msgstr ""
|
||||
"Ɏøn ɥɐʌǝ snɔɔǝssɟnllʎ sɥᴉɟʇǝd ʎønɹ ɔønɹsǝ sɔɥǝdnlǝ ɐnd ʎønɹ ɔɐlǝndɐɹ ᴉs nd "
|
||||
"ʇø dɐʇǝ."
|
||||
|
||||
#: openedx/features/content_tagging/models/base.py wiki/models/article.py
|
||||
msgid "owner"
|
||||
msgstr "øʍnǝɹ"
|
||||
|
||||
#: openedx/features/content_tagging/models/base.py
|
||||
msgid ""
|
||||
"Organization that is related to this taxonomy.If None, then this taxonomy is"
|
||||
" related to all organizations."
|
||||
msgstr ""
|
||||
"Øɹƃɐnᴉzɐʇᴉøn ʇɥɐʇ ᴉs ɹǝlɐʇǝd ʇø ʇɥᴉs ʇɐxønøɯʎ.Ɨɟ Nønǝ, ʇɥǝn ʇɥᴉs ʇɐxønøɯʎ ᴉs"
|
||||
" ɹǝlɐʇǝd ʇø ɐll øɹƃɐnᴉzɐʇᴉøns."
|
||||
|
||||
#: openedx/features/content_type_gating/models.py
|
||||
#: openedx/features/course_duration_limits/models.py
|
||||
#: lms/templates/support/feature_based_enrollments.html
|
||||
|
||||
Binary file not shown.
@@ -32,8 +32,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 0.1a\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2023-09-20 12:47+0000\n"
|
||||
"PO-Revision-Date: 2023-09-20 12:47:19.757119\n"
|
||||
"POT-Creation-Date: 2023-09-24 20:36+0000\n"
|
||||
"PO-Revision-Date: 2023-09-24 20:36:20.294880\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: openedx-translation <openedx-translation@googlegroups.com>\n"
|
||||
"Language: rtl\n"
|
||||
|
||||
@@ -55,7 +55,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 0.1a\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2023-08-27 20:43+0000\n"
|
||||
"POT-Creation-Date: 2023-09-17 20:43+0000\n"
|
||||
"PO-Revision-Date: 2019-01-20 20:43+0000\n"
|
||||
"Last-Translator: Waheed Ahmed <waheed@edx.org>, 2019\n"
|
||||
"Language-Team: Slovak (https://app.transifex.com/open-edx/teams/6205/sk/)\n"
|
||||
|
||||
@@ -85,7 +85,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 0.1a\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2023-08-27 20:43+0000\n"
|
||||
"POT-Creation-Date: 2023-09-17 20:43+0000\n"
|
||||
"PO-Revision-Date: 2019-01-20 20:43+0000\n"
|
||||
"Last-Translator: Waheed Ahmed <waheed@edx.org>, 2019\n"
|
||||
"Language-Team: Swahili (Kenya) (https://app.transifex.com/open-edx/teams/6205/sw_KE/)\n"
|
||||
|
||||
@@ -116,7 +116,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 0.1a\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2023-08-27 20:43+0000\n"
|
||||
"POT-Creation-Date: 2023-09-17 20:43+0000\n"
|
||||
"PO-Revision-Date: 2019-01-20 20:43+0000\n"
|
||||
"Last-Translator: Waheed Ahmed <waheed@edx.org>, 2019\n"
|
||||
"Language-Team: Thai (https://app.transifex.com/open-edx/teams/6205/th/)\n"
|
||||
|
||||
@@ -125,7 +125,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 0.1a\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2023-08-27 20:43+0000\n"
|
||||
"POT-Creation-Date: 2023-09-17 20:43+0000\n"
|
||||
"PO-Revision-Date: 2019-01-20 20:43+0000\n"
|
||||
"Last-Translator: Danylo Shcherbak <danylo.shcherbak@raccoongang.com>, 2020\n"
|
||||
"Language-Team: Ukrainian (https://app.transifex.com/open-edx/teams/6205/uk/)\n"
|
||||
|
||||
@@ -198,7 +198,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 0.1a\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2023-08-27 20:43+0000\n"
|
||||
"POT-Creation-Date: 2023-09-17 20:43+0000\n"
|
||||
"PO-Revision-Date: 2019-01-20 20:43+0000\n"
|
||||
"Last-Translator: Le Minh Tri <trilm@hihexa.com>, 2020\n"
|
||||
"Language-Team: Vietnamese (https://app.transifex.com/open-edx/teams/6205/vi/)\n"
|
||||
|
||||
@@ -403,7 +403,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 0.1a\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2023-08-27 20:43+0000\n"
|
||||
"POT-Creation-Date: 2023-09-17 20:43+0000\n"
|
||||
"PO-Revision-Date: 2019-01-20 20:43+0000\n"
|
||||
"Last-Translator: ifLab <webmaster@iflab.org>, 2019\n"
|
||||
"Language-Team: Chinese (China) (https://app.transifex.com/open-edx/teams/6205/zh_CN/)\n"
|
||||
|
||||
@@ -403,7 +403,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 0.1a\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2023-08-27 20:43+0000\n"
|
||||
"POT-Creation-Date: 2023-09-17 20:43+0000\n"
|
||||
"PO-Revision-Date: 2019-01-20 20:43+0000\n"
|
||||
"Last-Translator: ifLab <webmaster@iflab.org>, 2019\n"
|
||||
"Language-Team: Chinese (China) (https://app.transifex.com/open-edx/teams/6205/zh_CN/)\n"
|
||||
|
||||
@@ -177,7 +177,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 0.1a\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2023-08-27 20:43+0000\n"
|
||||
"POT-Creation-Date: 2023-09-17 20:43+0000\n"
|
||||
"PO-Revision-Date: 2019-01-20 20:43+0000\n"
|
||||
"Last-Translator: Waheed Ahmed <waheed@edx.org>, 2019\n"
|
||||
"Language-Team: Chinese (Taiwan) (https://app.transifex.com/open-edx/teams/6205/zh_TW/)\n"
|
||||
|
||||
@@ -3,17 +3,61 @@ Django Admin for Notifications
|
||||
"""
|
||||
|
||||
from django.contrib import admin
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from .base_notification import COURSE_NOTIFICATION_APPS, COURSE_NOTIFICATION_TYPES
|
||||
from .models import CourseNotificationPreference, Notification
|
||||
|
||||
|
||||
class NotificationAppNameListFilter(admin.SimpleListFilter):
|
||||
"""
|
||||
Shows list filter in django admin of notification apps
|
||||
"""
|
||||
title = _("Notification App")
|
||||
parameter_name = "app_name"
|
||||
|
||||
def lookups(self, request, model_admin):
|
||||
lookup_list = [
|
||||
(app_name, app_name)
|
||||
for app_name in COURSE_NOTIFICATION_APPS.keys()
|
||||
]
|
||||
return lookup_list
|
||||
|
||||
def queryset(self, request, queryset):
|
||||
app_name = self.value()
|
||||
if app_name not in COURSE_NOTIFICATION_APPS.keys():
|
||||
return queryset
|
||||
return queryset.filter(app_name=app_name)
|
||||
|
||||
|
||||
class NotificationTypeListFilter(admin.SimpleListFilter):
|
||||
"""
|
||||
Shows list filter in django admin of notification types
|
||||
"""
|
||||
title = _("Notification Type")
|
||||
parameter_name = "notification_type"
|
||||
|
||||
def lookups(self, request, model_admin):
|
||||
lookup_list = [
|
||||
(notification_type, notification_type)
|
||||
for notification_type in COURSE_NOTIFICATION_TYPES.keys()
|
||||
]
|
||||
return lookup_list
|
||||
|
||||
def queryset(self, request, queryset):
|
||||
notification_type = self.value()
|
||||
if notification_type not in COURSE_NOTIFICATION_TYPES.keys():
|
||||
return queryset
|
||||
return queryset.filter(notification_type=notification_type)
|
||||
|
||||
|
||||
class NotificationAdmin(admin.ModelAdmin):
|
||||
"""
|
||||
Admin for Notifications
|
||||
"""
|
||||
raw_id_fields = ('user',)
|
||||
search_fields = ('course_id', 'user__username')
|
||||
list_filter = ('app_name',)
|
||||
search_fields = ('course_id', 'app_name', 'notification_type', 'user__username')
|
||||
list_filter = (NotificationAppNameListFilter, NotificationTypeListFilter)
|
||||
|
||||
|
||||
class CourseNotificationPreferenceAdmin(admin.ModelAdmin):
|
||||
|
||||
@@ -20,9 +20,8 @@ celery>=5.2.2,<6.0.0
|
||||
# required for celery>=5.2.0;<5.3.0
|
||||
click>=8.0,<9.0
|
||||
|
||||
# django-storages version upgrade
|
||||
django-storages==1.13.2
|
||||
|
||||
# each version upgrade need release notes review.
|
||||
django-storages==1.14
|
||||
|
||||
# The team that owns this package will manually bump this package rather than having it pulled in automatically.
|
||||
# This is to allow them to better control its deployment and to do it in a process that works better
|
||||
@@ -33,7 +32,7 @@ edx-enterprise==4.3.1
|
||||
# mentioned on this issue https://github.com/openedx/edx-platform/issues/32884
|
||||
# 2. Versions from 1.5.0 to 2.0.0 have some migrations related changes.
|
||||
# so we're upgrading minor versions one by one.
|
||||
django-oauth-toolkit==1.5.0
|
||||
django-oauth-toolkit==1.6.2
|
||||
|
||||
|
||||
# constrained in opaque_keys. migration guide here: https://pymongo.readthedocs.io/en/4.0/migrate-to-pymongo4.html
|
||||
@@ -78,8 +77,7 @@ pylint<2.16.0 # greater version failing quality test. Fix them in seperate ticke
|
||||
# Deprecated version of the AWS SDK;
|
||||
# we should stop using this
|
||||
boto==2.39.0
|
||||
boto3==1.7.0 # Amazon Web Services SDK for Python
|
||||
botocore==1.10.84 # via boto3, s3transfer
|
||||
|
||||
|
||||
# adding these constraints to minimize boto3 and botocore changeset
|
||||
social-auth-core==4.3.0
|
||||
@@ -134,3 +132,4 @@ openedx-learning==0.1.6
|
||||
# existing custom parameter configurations unusable.
|
||||
# https://github.com/openedx/xblock-lti-consumer/issues/410 has been opened to track a fix
|
||||
lti-consumer-xblock==9.6.1
|
||||
|
||||
|
||||
@@ -77,16 +77,14 @@ boto==2.39.0
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/kernel.in
|
||||
boto3==1.7.0
|
||||
boto3==1.28.53
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/kernel.in
|
||||
# django-ses
|
||||
# fs-s3fs
|
||||
# ora2
|
||||
botocore==1.10.84
|
||||
botocore==1.31.53
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/kernel.in
|
||||
# boto3
|
||||
# s3transfer
|
||||
@@ -259,7 +257,7 @@ django-celery-results==2.5.1
|
||||
# via -r requirements/edx/kernel.in
|
||||
django-classy-tags==4.1.0
|
||||
# via django-sekizai
|
||||
django-config-models==2.5.0
|
||||
django-config-models==2.5.1
|
||||
# via
|
||||
# -r requirements/edx/kernel.in
|
||||
# edx-enterprise
|
||||
@@ -325,7 +323,7 @@ django-multi-email-field==0.7.0
|
||||
# via edx-enterprise
|
||||
django-mysql==4.11.0
|
||||
# via -r requirements/edx/kernel.in
|
||||
django-oauth-toolkit==1.5.0
|
||||
django-oauth-toolkit==1.6.2
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/kernel.in
|
||||
@@ -357,7 +355,7 @@ django-statici18n==2.4.0
|
||||
# -r requirements/edx/kernel.in
|
||||
# lti-consumer-xblock
|
||||
# xblock-drag-and-drop-v2
|
||||
django-storages==1.13.2
|
||||
django-storages==1.14
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/kernel.in
|
||||
@@ -402,10 +400,6 @@ djangorestframework==3.14.0
|
||||
# super-csv
|
||||
djangorestframework-xml==2.0.0
|
||||
# via edx-enterprise
|
||||
docutils==0.19
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# botocore
|
||||
done-xblock==2.1.0
|
||||
# via -r requirements/edx/bundled.in
|
||||
drf-jwt==1.19.2
|
||||
@@ -490,7 +484,7 @@ edx-enterprise==4.3.1
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/kernel.in
|
||||
edx-event-bus-kafka==5.4.0
|
||||
edx-event-bus-kafka==5.5.0
|
||||
# via -r requirements/edx/kernel.in
|
||||
edx-event-bus-redis==0.3.1
|
||||
# via -r requirements/edx/kernel.in
|
||||
@@ -500,7 +494,7 @@ edx-milestones==0.5.0
|
||||
# via -r requirements/edx/kernel.in
|
||||
edx-name-affirmation==2.3.6
|
||||
# via -r requirements/edx/kernel.in
|
||||
edx-opaque-keys[django]==2.5.0
|
||||
edx-opaque-keys[django]==2.5.1
|
||||
# via
|
||||
# -r requirements/edx/kernel.in
|
||||
# -r requirements/edx/paver.txt
|
||||
@@ -636,7 +630,7 @@ jinja2==3.1.2
|
||||
# via
|
||||
# code-annotations
|
||||
# coreschema
|
||||
jmespath==0.10.0
|
||||
jmespath==1.0.1
|
||||
# via
|
||||
# boto3
|
||||
# botocore
|
||||
@@ -778,7 +772,7 @@ openedx-django-pyfs==3.4.0
|
||||
# xblock
|
||||
openedx-django-require==2.1.0
|
||||
# via -r requirements/edx/kernel.in
|
||||
openedx-django-wiki==2.0.1
|
||||
openedx-django-wiki==2.0.3
|
||||
# via -r requirements/edx/kernel.in
|
||||
openedx-events==8.5.0
|
||||
# via
|
||||
@@ -1034,7 +1028,7 @@ rules==3.3
|
||||
# edx-enterprise
|
||||
# edx-proctoring
|
||||
# openedx-learning
|
||||
s3transfer==0.1.13
|
||||
s3transfer==0.6.2
|
||||
# via boto3
|
||||
sailthru-client==2.2.3
|
||||
# via edx-ace
|
||||
@@ -1062,7 +1056,6 @@ six==1.16.0
|
||||
# chem
|
||||
# codejail-includes
|
||||
# crowdsourcehinter-xblock
|
||||
# django-oauth-toolkit
|
||||
# edx-ace
|
||||
# edx-auth-backends
|
||||
# edx-ccx-keys
|
||||
@@ -1170,6 +1163,7 @@ urllib3==1.26.16
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/paver.txt
|
||||
# botocore
|
||||
# elasticsearch
|
||||
# py2neo
|
||||
# requests
|
||||
|
||||
@@ -145,17 +145,15 @@ boto==2.39.0
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/doc.txt
|
||||
# -r requirements/edx/testing.txt
|
||||
boto3==1.7.0
|
||||
boto3==1.28.53
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/doc.txt
|
||||
# -r requirements/edx/testing.txt
|
||||
# django-ses
|
||||
# fs-s3fs
|
||||
# ora2
|
||||
botocore==1.10.84
|
||||
botocore==1.31.53
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/doc.txt
|
||||
# -r requirements/edx/testing.txt
|
||||
# boto3
|
||||
@@ -431,7 +429,7 @@ django-classy-tags==4.1.0
|
||||
# -r requirements/edx/doc.txt
|
||||
# -r requirements/edx/testing.txt
|
||||
# django-sekizai
|
||||
django-config-models==2.5.0
|
||||
django-config-models==2.5.1
|
||||
# via
|
||||
# -r requirements/edx/doc.txt
|
||||
# -r requirements/edx/testing.txt
|
||||
@@ -524,7 +522,7 @@ django-mysql==4.11.0
|
||||
# via
|
||||
# -r requirements/edx/doc.txt
|
||||
# -r requirements/edx/testing.txt
|
||||
django-oauth-toolkit==1.5.0
|
||||
django-oauth-toolkit==1.6.2
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/doc.txt
|
||||
@@ -571,7 +569,7 @@ django-statici18n==2.4.0
|
||||
# -r requirements/edx/testing.txt
|
||||
# lti-consumer-xblock
|
||||
# xblock-drag-and-drop-v2
|
||||
django-storages==1.13.2
|
||||
django-storages==1.14
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/doc.txt
|
||||
@@ -640,8 +638,6 @@ docutils==0.19
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/doc.txt
|
||||
# -r requirements/edx/testing.txt
|
||||
# botocore
|
||||
# pydata-sphinx-theme
|
||||
# sphinx
|
||||
# sphinx-mdinclude
|
||||
@@ -759,7 +755,7 @@ edx-enterprise==4.3.1
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/doc.txt
|
||||
# -r requirements/edx/testing.txt
|
||||
edx-event-bus-kafka==5.4.0
|
||||
edx-event-bus-kafka==5.5.0
|
||||
# via
|
||||
# -r requirements/edx/doc.txt
|
||||
# -r requirements/edx/testing.txt
|
||||
@@ -782,7 +778,7 @@ edx-name-affirmation==2.3.6
|
||||
# via
|
||||
# -r requirements/edx/doc.txt
|
||||
# -r requirements/edx/testing.txt
|
||||
edx-opaque-keys[django]==2.5.0
|
||||
edx-opaque-keys[django]==2.5.1
|
||||
# via
|
||||
# -r requirements/edx/doc.txt
|
||||
# -r requirements/edx/testing.txt
|
||||
@@ -950,7 +946,7 @@ gitdb==4.0.10
|
||||
# via
|
||||
# -r requirements/edx/doc.txt
|
||||
# gitpython
|
||||
gitpython==3.1.36
|
||||
gitpython==3.1.37
|
||||
# via -r requirements/edx/doc.txt
|
||||
glob2==0.7
|
||||
# via
|
||||
@@ -1064,7 +1060,7 @@ jinja2==3.1.2
|
||||
# coreschema
|
||||
# diff-cover
|
||||
# sphinx
|
||||
jmespath==0.10.0
|
||||
jmespath==1.0.1
|
||||
# via
|
||||
# -r requirements/edx/doc.txt
|
||||
# -r requirements/edx/testing.txt
|
||||
@@ -1305,7 +1301,7 @@ openedx-django-require==2.1.0
|
||||
# via
|
||||
# -r requirements/edx/doc.txt
|
||||
# -r requirements/edx/testing.txt
|
||||
openedx-django-wiki==2.0.1
|
||||
openedx-django-wiki==2.0.3
|
||||
# via
|
||||
# -r requirements/edx/doc.txt
|
||||
# -r requirements/edx/testing.txt
|
||||
@@ -1792,7 +1788,7 @@ rules==3.3
|
||||
# edx-enterprise
|
||||
# edx-proctoring
|
||||
# openedx-learning
|
||||
s3transfer==0.1.13
|
||||
s3transfer==0.6.2
|
||||
# via
|
||||
# -r requirements/edx/doc.txt
|
||||
# -r requirements/edx/testing.txt
|
||||
@@ -1841,7 +1837,6 @@ six==1.16.0
|
||||
# chem
|
||||
# codejail-includes
|
||||
# crowdsourcehinter-xblock
|
||||
# django-oauth-toolkit
|
||||
# edx-ace
|
||||
# edx-auth-backends
|
||||
# edx-ccx-keys
|
||||
@@ -2118,6 +2113,7 @@ urllib3==1.26.16
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/doc.txt
|
||||
# -r requirements/edx/testing.txt
|
||||
# botocore
|
||||
# elasticsearch
|
||||
# pact-python
|
||||
# py2neo
|
||||
|
||||
@@ -103,16 +103,14 @@ boto==2.39.0
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/base.txt
|
||||
boto3==1.7.0
|
||||
boto3==1.28.53
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/base.txt
|
||||
# django-ses
|
||||
# fs-s3fs
|
||||
# ora2
|
||||
botocore==1.10.84
|
||||
botocore==1.31.53
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/base.txt
|
||||
# boto3
|
||||
# s3transfer
|
||||
@@ -312,7 +310,7 @@ django-classy-tags==4.1.0
|
||||
# via
|
||||
# -r requirements/edx/base.txt
|
||||
# django-sekizai
|
||||
django-config-models==2.5.0
|
||||
django-config-models==2.5.1
|
||||
# via
|
||||
# -r requirements/edx/base.txt
|
||||
# edx-enterprise
|
||||
@@ -386,7 +384,7 @@ django-multi-email-field==0.7.0
|
||||
# edx-enterprise
|
||||
django-mysql==4.11.0
|
||||
# via -r requirements/edx/base.txt
|
||||
django-oauth-toolkit==1.5.0
|
||||
django-oauth-toolkit==1.6.2
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/base.txt
|
||||
@@ -420,7 +418,7 @@ django-statici18n==2.4.0
|
||||
# -r requirements/edx/base.txt
|
||||
# lti-consumer-xblock
|
||||
# xblock-drag-and-drop-v2
|
||||
django-storages==1.13.2
|
||||
django-storages==1.14
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/base.txt
|
||||
@@ -470,8 +468,6 @@ djangorestframework-xml==2.0.0
|
||||
docutils==0.19
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/base.txt
|
||||
# botocore
|
||||
# pydata-sphinx-theme
|
||||
# sphinx
|
||||
# sphinx-mdinclude
|
||||
@@ -564,7 +560,7 @@ edx-enterprise==4.3.1
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/base.txt
|
||||
edx-event-bus-kafka==5.4.0
|
||||
edx-event-bus-kafka==5.5.0
|
||||
# via -r requirements/edx/base.txt
|
||||
edx-event-bus-redis==0.3.1
|
||||
# via -r requirements/edx/base.txt
|
||||
@@ -576,7 +572,7 @@ edx-milestones==0.5.0
|
||||
# via -r requirements/edx/base.txt
|
||||
edx-name-affirmation==2.3.6
|
||||
# via -r requirements/edx/base.txt
|
||||
edx-opaque-keys[django]==2.5.0
|
||||
edx-opaque-keys[django]==2.5.1
|
||||
# via
|
||||
# -r requirements/edx/base.txt
|
||||
# edx-bulk-grades
|
||||
@@ -686,7 +682,7 @@ geoip2==4.7.0
|
||||
# via -r requirements/edx/base.txt
|
||||
gitdb==4.0.10
|
||||
# via gitpython
|
||||
gitpython==3.1.36
|
||||
gitpython==3.1.37
|
||||
# via -r requirements/edx/doc.in
|
||||
glob2==0.7
|
||||
# via -r requirements/edx/base.txt
|
||||
@@ -744,7 +740,7 @@ jinja2==3.1.2
|
||||
# code-annotations
|
||||
# coreschema
|
||||
# sphinx
|
||||
jmespath==0.10.0
|
||||
jmespath==1.0.1
|
||||
# via
|
||||
# -r requirements/edx/base.txt
|
||||
# boto3
|
||||
@@ -916,7 +912,7 @@ openedx-django-pyfs==3.4.0
|
||||
# xblock
|
||||
openedx-django-require==2.1.0
|
||||
# via -r requirements/edx/base.txt
|
||||
openedx-django-wiki==2.0.1
|
||||
openedx-django-wiki==2.0.3
|
||||
# via -r requirements/edx/base.txt
|
||||
openedx-events==8.5.0
|
||||
# via
|
||||
@@ -1222,7 +1218,7 @@ rules==3.3
|
||||
# edx-enterprise
|
||||
# edx-proctoring
|
||||
# openedx-learning
|
||||
s3transfer==0.1.13
|
||||
s3transfer==0.6.2
|
||||
# via
|
||||
# -r requirements/edx/base.txt
|
||||
# boto3
|
||||
@@ -1256,7 +1252,6 @@ six==1.16.0
|
||||
# chem
|
||||
# codejail-includes
|
||||
# crowdsourcehinter-xblock
|
||||
# django-oauth-toolkit
|
||||
# edx-ace
|
||||
# edx-auth-backends
|
||||
# edx-ccx-keys
|
||||
@@ -1425,6 +1420,7 @@ urllib3==1.26.16
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/base.txt
|
||||
# botocore
|
||||
# elasticsearch
|
||||
# py2neo
|
||||
# requests
|
||||
|
||||
@@ -10,7 +10,7 @@ charset-normalizer==2.0.12
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# requests
|
||||
edx-opaque-keys==2.5.0
|
||||
edx-opaque-keys==2.5.1
|
||||
# via -r requirements/edx/paver.in
|
||||
idna==3.4
|
||||
# via requests
|
||||
|
||||
@@ -110,16 +110,14 @@ boto==2.39.0
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/base.txt
|
||||
boto3==1.7.0
|
||||
boto3==1.28.53
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/base.txt
|
||||
# django-ses
|
||||
# fs-s3fs
|
||||
# ora2
|
||||
botocore==1.10.84
|
||||
botocore==1.31.53
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/base.txt
|
||||
# boto3
|
||||
# s3transfer
|
||||
@@ -345,7 +343,7 @@ django-classy-tags==4.1.0
|
||||
# via
|
||||
# -r requirements/edx/base.txt
|
||||
# django-sekizai
|
||||
django-config-models==2.5.0
|
||||
django-config-models==2.5.1
|
||||
# via
|
||||
# -r requirements/edx/base.txt
|
||||
# edx-enterprise
|
||||
@@ -419,7 +417,7 @@ django-multi-email-field==0.7.0
|
||||
# edx-enterprise
|
||||
django-mysql==4.11.0
|
||||
# via -r requirements/edx/base.txt
|
||||
django-oauth-toolkit==1.5.0
|
||||
django-oauth-toolkit==1.6.2
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/base.txt
|
||||
@@ -453,7 +451,7 @@ django-statici18n==2.4.0
|
||||
# -r requirements/edx/base.txt
|
||||
# lti-consumer-xblock
|
||||
# xblock-drag-and-drop-v2
|
||||
django-storages==1.13.2
|
||||
django-storages==1.14
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/base.txt
|
||||
@@ -500,11 +498,6 @@ djangorestframework-xml==2.0.0
|
||||
# via
|
||||
# -r requirements/edx/base.txt
|
||||
# edx-enterprise
|
||||
docutils==0.19
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/base.txt
|
||||
# botocore
|
||||
done-xblock==2.1.0
|
||||
# via -r requirements/edx/base.txt
|
||||
drf-jwt==1.19.2
|
||||
@@ -594,7 +587,7 @@ edx-enterprise==4.3.1
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/base.txt
|
||||
edx-event-bus-kafka==5.4.0
|
||||
edx-event-bus-kafka==5.5.0
|
||||
# via -r requirements/edx/base.txt
|
||||
edx-event-bus-redis==0.3.1
|
||||
# via -r requirements/edx/base.txt
|
||||
@@ -609,7 +602,7 @@ edx-milestones==0.5.0
|
||||
# via -r requirements/edx/base.txt
|
||||
edx-name-affirmation==2.3.6
|
||||
# via -r requirements/edx/base.txt
|
||||
edx-opaque-keys[django]==2.5.0
|
||||
edx-opaque-keys[django]==2.5.1
|
||||
# via
|
||||
# -r requirements/edx/base.txt
|
||||
# edx-bulk-grades
|
||||
@@ -810,7 +803,7 @@ jinja2==3.1.2
|
||||
# code-annotations
|
||||
# coreschema
|
||||
# diff-cover
|
||||
jmespath==0.10.0
|
||||
jmespath==1.0.1
|
||||
# via
|
||||
# -r requirements/edx/base.txt
|
||||
# boto3
|
||||
@@ -986,7 +979,7 @@ openedx-django-pyfs==3.4.0
|
||||
# xblock
|
||||
openedx-django-require==2.1.0
|
||||
# via -r requirements/edx/base.txt
|
||||
openedx-django-wiki==2.0.1
|
||||
openedx-django-wiki==2.0.3
|
||||
# via -r requirements/edx/base.txt
|
||||
openedx-events==8.5.0
|
||||
# via
|
||||
@@ -1359,7 +1352,7 @@ rules==3.3
|
||||
# edx-enterprise
|
||||
# edx-proctoring
|
||||
# openedx-learning
|
||||
s3transfer==0.1.13
|
||||
s3transfer==0.6.2
|
||||
# via
|
||||
# -r requirements/edx/base.txt
|
||||
# boto3
|
||||
@@ -1399,7 +1392,6 @@ six==1.16.0
|
||||
# chem
|
||||
# codejail-includes
|
||||
# crowdsourcehinter-xblock
|
||||
# django-oauth-toolkit
|
||||
# edx-ace
|
||||
# edx-auth-backends
|
||||
# edx-ccx-keys
|
||||
@@ -1565,6 +1557,7 @@ urllib3==1.26.16
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/base.txt
|
||||
# botocore
|
||||
# elasticsearch
|
||||
# pact-python
|
||||
# py2neo
|
||||
|
||||
Reference in New Issue
Block a user