This commit is contained in:
Markos Gogoulos
2026-05-06 10:15:17 +03:00
parent c06cfb3983
commit cb0953f8bb
11 changed files with 28 additions and 65 deletions
+1 -1
View File
@@ -1 +1 @@
VERSION = "8.0.1a"
VERSION = "8.0.1b"
-4
View File
@@ -79,10 +79,6 @@ urlpatterns = [
rf"^api/v1/media/{friendly_token}/trim_video$",
views.trim_video,
),
re_path(
rf"^api/v1/media/{friendly_token}/share$",
views.MediaShare.as_view(),
),
re_path(r"^api/v1/categories$", views.CategoryList.as_view()),
re_path(r"^api/v1/categories/contributor$", views.CategoryListContributor.as_view()),
re_path(r"^api/v1/tags$", views.TagList.as_view()),
-1
View File
@@ -9,7 +9,6 @@ from .media import MediaBulkUserActions # noqa: F401
from .media import MediaDetail # noqa: F401
from .media import MediaList # noqa: F401
from .media import MediaSearch # noqa: F401
from .media import MediaShare # noqa: F401
from .pages import about # noqa: F401
from .pages import add_subtitle # noqa: F401
from .pages import approval_required # noqa: F401
-28
View File
@@ -1233,31 +1233,3 @@ class MediaSearch(APIView):
page = paginator.paginate_queryset(media, request)
serializer = MediaSearchSerializer(page, many=True, context={"request": request})
return paginator.get_paginated_response(serializer.data)
class MediaShare(APIView):
"""Create a self-referential MediaPermission to mark a media as shared."""
def post(self, request, friendly_token):
if not request.user.is_authenticated:
return Response({'error': 'Authentication required'}, status=status.HTTP_401_UNAUTHORIZED)
media = get_object_or_404(Media, friendly_token=friendly_token)
if media.user != request.user and not is_mediacms_editor(request.user):
return Response({'error': 'Permission denied'}, status=status.HTTP_403_FORBIDDEN)
MediaPermission.objects.get_or_create(
media=media,
user=request.user,
defaults={'owner_user': request.user, 'permission': 'owner'},
)
lti_session = request.session.get('lti_session', {})
context_id = lti_session.get('context_id')
if context_id:
category = Category.objects.filter(lti_context_id=context_id, is_rbac_category=True).first()
if category:
EmbedMediaCourse.objects.get_or_create(media=media, category=category)
return Response({'status': 'ok'})
@@ -171,7 +171,6 @@ class ProfileMediaPage extends Page {
const baseUrl = window.location.origin;
const embedUrl = `${baseUrl}/embed?m=${mediaId}`;
const sendPostMessage = () => {
if (window.parent !== window) {
window.parent.postMessage({
type: 'videoSelected',
@@ -179,17 +178,6 @@ class ProfileMediaPage extends Page {
videoId: mediaId,
}, '*');
}
};
// Share first, then notify parent — postMessage can cause parent to navigate away
// which would cancel an in-flight fetch if called in the wrong order
fetch(`/api/v1/media/${mediaId}/share`, {
method: 'POST',
headers: {
'X-CSRFToken': this.props.bulkActions.getCsrfToken(),
'Content-Type': 'application/json',
},
}).then(sendPostMessage).catch(sendPostMessage);
}
}
+15 -1
View File
@@ -30,7 +30,7 @@ from pylti1p3.exception import LtiException
from pylti1p3.message_launch import MessageLaunch
from pylti1p3.oidc_login import OIDCLogin
from files.models import Media, MediaPermission
from files.models import Category, EmbedMediaCourse, Media, MediaPermission
from rbac.models import RBACMembership
from .adapters import DjangoRequest, DjangoSessionService, DjangoToolConfig
@@ -728,6 +728,20 @@ class EmbedMediaLTIView(View):
context_id = lti_session.get('context_id')
platform_id = lti_session.get('platform_id')
# Auto-share: when the media owner loads their own embed via LTI,
# mark it as shared and link it to the course. This fires on the
# teacher's first page view after saving (Moodle redirects there automatically).
if media.user == request.user:
MediaPermission.objects.get_or_create(
media=media,
user=request.user,
defaults={'owner_user': request.user, 'permission': 'owner'},
)
if context_id:
category = Category.objects.filter(lti_context_id=context_id, is_rbac_category=True).first()
if category:
EmbedMediaCourse.objects.get_or_create(media=media, category=category)
if media.is_shared and context_id and platform_id:
try:
resource_link = (
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -7
View File
@@ -269,13 +269,7 @@
}, '*');
};
fetch('/api/v1/media/' + mediaId + '/share', {
method: 'POST',
headers: {
'X-CSRFToken': getCSRFToken(),
'Content-Type': 'application/json',
},
}).then(sendPostMsg).catch(sendPostMsg);
sendPostMsg();
return;
}
setTimeout(function(){ window.location.href = response.media_url; }, 500);