From ae7ee037d6f76f5337d536b7c0514b1edf21ced6 Mon Sep 17 00:00:00 2001 From: Nikolas Nyby Date: Mon, 3 Oct 2022 19:39:17 -0400 Subject: [PATCH] WIP: Add simple AssetCreateView #4647 Create basic form for creating a Mediathread asset based on an external image or video source. --- mediathread/assetmgr/tests/test_views.py | 14 ++--- mediathread/assetmgr/views.py | 62 ++++++++++++++++++- .../templates/main/collection_add.html | 54 ++++++++++++++-- mediathread/urls.py | 7 ++- 4 files changed, 120 insertions(+), 17 deletions(-) diff --git a/mediathread/assetmgr/tests/test_views.py b/mediathread/assetmgr/tests/test_views.py index 6d2112d198..86a200f302 100644 --- a/mediathread/assetmgr/tests/test_views.py +++ b/mediathread/assetmgr/tests/test_views.py @@ -18,7 +18,7 @@ EMBED_WIDTH, EMBED_HEIGHT, asset_workspace_courselookup, RedirectToExternalCollectionView, - RedirectToUploaderView, AssetCreateView, AssetEmbedListView, + RedirectToUploaderView, ExternalAssetCreateView, AssetEmbedListView, _parse_domain, AssetEmbedView, annotation_delete, annotation_create_global, annotation_create, AssetUpdateView ) @@ -86,7 +86,7 @@ def test_sources_from_args(self): 'image': 'x' * 5000, # too long 'url': 'https://www.youtube.com/abcdefghi'} request = RequestFactory().post('/save/', data) - sources = AssetCreateView.sources_from_args(request) + sources = ExternalAssetCreateView.sources_from_args(request) self.assertEquals(len(sources.keys()), 0) @@ -95,7 +95,7 @@ def test_sources_from_args(self): 'image': 'https://www.flickr.com/', 'image-metadata': ['w720h526;text/html']} request = RequestFactory().post('/save/', data) - sources = AssetCreateView.sources_from_args(request) + sources = ExternalAssetCreateView.sources_from_args(request) self.assertEquals(len(sources.keys()), 2) self.assertEquals(sources['image'].url, 'https://www.flickr.com/') self.assertTrue(sources['image'].primary) @@ -111,7 +111,7 @@ def test_sources_from_args(self): 'metadata-description': 'Video description', } request = RequestFactory().post('/save/', data) - sources = AssetCreateView.sources_from_args(request) + sources = ExternalAssetCreateView.sources_from_args(request) self.assertEquals(len(sources.keys()), 2) self.assertEquals(sources['video'].url, 'http://www.example.com/video.mp4') @@ -120,7 +120,7 @@ def test_sources_from_args(self): self.assertEquals(sources['video'].height, 358) def test_parse_user(self): - view = AssetCreateView() + view = ExternalAssetCreateView() request = RequestFactory().get('/') request.course = self.sample_course @@ -222,7 +222,7 @@ def test_asset_create_via_bookmarklet(self): request.user = self.instructor_one request.course = self.sample_course - view = AssetCreateView() + view = ExternalAssetCreateView() view.request = request response = view.post(request) @@ -240,7 +240,7 @@ def test_asset_create_via_bookmarklet(self): request.user = self.instructor_one request.course = self.sample_course - view = AssetCreateView() + view = ExternalAssetCreateView() view.request = request response = view.post(request) diff --git a/mediathread/assetmgr/views.py b/mediathread/assetmgr/views.py index c1141f685a..1750160208 100644 --- a/mediathread/assetmgr/views.py +++ b/mediathread/assetmgr/views.py @@ -155,7 +155,7 @@ def post(self, request): # This view is used by Mediathread's browser extension, so disable CSRF # until we implement this in the extension. @method_decorator(csrf_exempt, name='dispatch') -class AssetCreateView(View): +class ExternalAssetCreateView(View): OPERATION_TAGS = ('jump', 'title', 'noui', 'v', 'share', 'as', 'set_course', 'secret') @@ -328,6 +328,66 @@ def post(self, request): return HttpResponseRedirect(asset_url) +class AssetCreateView(LoggedInCourseMixin, View): + """ + View for creating an Asset via an uploaded media object. + """ + http_method_names = ['post'] + + def dispatch(self, request, *args, **kwargs): + r = super().dispatch(request, *args, **kwargs) + + # @todo - update for pdf permissions when that's ready to go + if not course_details.can_upload_image(request.user, request.course): + raise PermissionDenied + + return r + + def post(self, request, *args, **kwargs): + if (not request.POST.get('title')) or \ + (not request.POST.get('url')): + return HttpResponseBadRequest( + 'Title and URL are required to make an asset.') + + title = request.POST.get('title').strip() + url = request.POST.get('url') + + author = request.user + if request.user.is_staff and request.POST.get('as'): + upload_as = request.POST.get('as') + author = get_object_or_404(User, username=upload_as) + + asset = Asset.objects.create( + course=request.course, title=title, author=author) + asset.global_annotation(request.user, True) + + label = 'image' + if url.endswith('.pdf'): + label = 'pdf' + # Dimensions are not needed for PDF display. + width = 0 + height = 0 + else: + width = request.POST.get('width') + height = request.POST.get('height') + + Source.objects.create( + asset=asset, url=url, + primary=True, + width=width, height=height, + label=label) + + asset_url = reverse('asset-view', args=[request.course.pk, asset.pk]) + + messages.success( + request, + 'The {} item '.format( + asset_url, asset.title + ) + 'has been added to your collection.') + + return redirect('asset-view', request.course.pk, asset.pk) + + class UploadedAssetCreateView(LoggedInCourseMixin, View): """ View for creating an Asset via an uploaded media object. diff --git a/mediathread/templates/main/collection_add.html b/mediathread/templates/main/collection_add.html index 0bacbdfa6b..0fbe7a520c 100644 --- a/mediathread/templates/main/collection_add.html +++ b/mediathread/templates/main/collection_add.html @@ -179,16 +179,58 @@
IMAGE
Import Media
+ +
+
+ + + + Right-click source image and "Copy image address" + +
+
+ + +
+ +
+ +
+

- Install Mediathread’s Google Chrome - extension to import assets like video, audio, and + Alternatively, you can install + Mediathread’s Google Chrome extension + to import assets like video, audio, and images into this course from various sites across the web. -

  • Visit the Chrome Web Store and make sure to click Add To Chrome.
  • -
  • Once added to your browser, you can click on the Extension icon next - to the Address Bar to pin the Mediathread extension for easier access.
  • -
  • You can click the extension to collect single media items from sites like Flickr, YouTube, and Google Images.
  • +
      +
    • + Visit the Chrome Web Store and + make sure to click Add To + Chrome. +
    • +
    • + Once added to your browser, you + can click on the Extension icon + next to the Address Bar to pin + the Mediathread extension for + easier access. +
    • +
    • + You can click the extension to + collect single media items from + sites like Flickr, YouTube, and + Google Images. +
    You must be using a browser in the Chrome family diff --git a/mediathread/urls.py b/mediathread/urls.py index 71cb443f1a..2de7efe262 100644 --- a/mediathread/urls.py +++ b/mediathread/urls.py @@ -23,7 +23,8 @@ AssetDetailView, ReactAssetDetailView, TagCollectionView, RedirectToExternalCollectionView, RedirectToUploaderView, - AssetCreateView, BookmarkletMigrationView, AssetUpdateView) + ExternalAssetCreateView, BookmarkletMigrationView, AssetUpdateView +) from mediathread.main.forms import CustomRegistrationForm from mediathread.main.views import ( error_500, @@ -284,8 +285,8 @@ path('course//reports/', include('mediathread.reports.urls')), - # Bookmarklet, Wardenclyffe, Staff custom asset entry - path('save/', AssetCreateView.as_view(), name='asset-save'), + # Browser Extension, Wardenclyffe, Staff custom asset entry + path('save/', ExternalAssetCreateView.as_view(), name='asset-save'), path('update/', AssetUpdateView.as_view(), name='asset-update-view'), path('setting//', set_user_setting),