def test_get_embed(self): embed = get_embed('www.test.com/1234', max_width=400, finder=self.dummy_finder) # Check that the embed is correct self.assertEqual(embed.title, "Test: www.test.com/1234") self.assertEqual(embed.type, 'video') self.assertEqual(embed.width, 400) # Check ratio calculations self.assertEqual(embed.ratio, 480 / 400) self.assertEqual(embed.ratio_css, '120.0%') self.assertTrue(embed.is_responsive) # Check that there has only been one hit to the backend self.assertEqual(self.hit_count, 1) # Look for the same embed again and check the hit count hasn't increased embed = get_embed('www.test.com/1234', max_width=400, finder=self.dummy_finder) self.assertEqual(self.hit_count, 1) # Look for a different embed, hit count should increase embed = get_embed('www.test.com/4321', max_width=400, finder=self.dummy_finder) self.assertEqual(self.hit_count, 2) # Look for the same embed with a different width, this should also increase hit count embed = get_embed('www.test.com/4321', finder=self.dummy_finder) self.assertEqual(self.hit_count, 3)
def test_get_embed_cache_until(self): embed = get_embed("www.test.com/1234", max_width=400, finder=self.dummy_cache_until_finder) self.assertEqual(embed.cache_until, make_aware(datetime.datetime(2001, 2, 3))) self.assertEqual(self.hit_count, 1) # expired cache_until should be ignored embed_2 = get_embed("www.test.com/1234", max_width=400, finder=self.dummy_cache_until_finder) self.assertEqual(self.hit_count, 2) # future cache_until should not be ignored future_dt = now() + datetime.timedelta(minutes=1) embed.cache_until = future_dt embed.save() embed_3 = get_embed("www.test.com/1234", max_width=400, finder=self.dummy_cache_until_finder) self.assertEqual(self.hit_count, 2) # ensure we've received the same embed self.assertEqual(embed, embed_2) self.assertEqual(embed, embed_3) self.assertEqual(embed_3.cache_until, future_dt)
def test_get_embed_responsive(self): embed = get_embed('www.test.com/1234', max_width=400, finder=self.dummy_finder) # Check that the embed is correct self.assertEqual(embed.title, "Test: www.test.com/1234") self.assertEqual(embed.type, 'video') self.assertEqual(embed.width, 400) # Check ratio calculations self.assertEqual(embed.ratio, 480 / 400) self.assertEqual(embed.ratio_css, '120.0%') self.assertTrue(embed.is_responsive) # Check that there has only been one hit to the backend self.assertEqual(self.hit_count, 1) # Look for the same embed again and check the hit count hasn't increased embed = get_embed('www.test.com/1234', max_width=400, finder=self.dummy_finder) self.assertEqual(self.hit_count, 1) # Look for a different embed, hit count should increase embed = get_embed('www.test.com/4321', max_width=400, finder=self.dummy_finder) self.assertEqual(self.hit_count, 2) # Look for the same embed with a different width, this should also increase hit count embed = get_embed('www.test.com/4321', finder=self.dummy_finder) self.assertEqual(self.hit_count, 3)
def embed_chooser_upload(request): if request.method == "POST": form = EmbedForm(request.POST, request.FILES, prefix="embed-chooser") if form.is_valid(): error = None try: embed_html = embed_to_editor_html(form.cleaned_data["url"]) embed_obj = embeds.get_embed(form.cleaned_data["url"]) embed_data = { "embedType": embed_obj.type, "url": embed_obj.url, "providerName": embed_obj.provider_name, "authorName": embed_obj.author_name, "thumbnail": embed_obj.thumbnail_url, "title": embed_obj.title, } return render_modal_workflow( request, None, None, None, json_data={ "step": "embed_chosen", "embed_html": embed_html, "embed_data": embed_data, }, ) except AccessDeniedEmbedlyException: error = _( "There seems to be a problem with your embedly API key. Please check your settings." ) except (EmbedNotFoundException, EmbedUnsupportedProviderException): error = _("Cannot find an embed for this URL.") except EmbedlyException: error = _( "There seems to be an error with Embedly while trying to embed this URL." " Please try again later." ) if error: errors = form._errors.setdefault("url", ErrorList()) errors.append(error) return render_modal_workflow( request, "non_admin_draftail/embed/chooser.html", None, {"form": form}, json_data={"step": "chooser"}, ) else: form = EmbedForm(prefix="embed-chooser") return render_modal_workflow( request, "non_admin_draftail/embed/chooser.html", None, {"form": form}, json_data={"step": "chooser"}, )
def serialise_block(self, block, value): if hasattr(block, 'to_graphql_representation'): return block.to_graphql_representation(value) elif isinstance(block, blocks.RichTextBlock): return serialize_rich_text(value.source) elif isinstance(block, EmbedBlock): try: embed = get_embed(value.url) return { 'html': embed.html, 'url': value.url, } except EmbedException: return { 'html': '', 'url': None } elif isinstance(block, ImageChooserBlock): # FIXME return { 'id': value.id, 'alt': value.title, 'src': settings.MEDIA_PREFIX + value.file.url, 'hash': value.get_file_hash() } elif isinstance(block, blocks.FieldBlock): return value elif isinstance(block, blocks.StructBlock): return self.serialise_struct_block(block, value) elif isinstance(block, blocks.ListBlock): return self.serialise_list_block(block, value) elif isinstance(block, blocks.StreamBlock): return self.serialise_stream_block(block, value)
def arbitrary_video(video, width, height, classes=None): """ Renders an embedded video with the given width and height. If passed in, 'classes' must be a string of CSS class names. """ try: embed = embeds.get_embed(video.url, width) html = embed.html # Replace the calculated height value with what the user specified. html = re.sub(r'height="(\d+)"', 'height="{}"'.format(height), html) # Add the provider name as a data attr, so that the javascript can determine how to interact with this iframe. html = re.sub(r'<iframe', '<iframe data-provider="{}"'.format(embed.provider_name), html) # Add any classes that may have been specified. if classes: html = re.sub(r'<iframe', f'<iframe class="{classes}"', html) # Remove the video player chrome. if embed.provider_name == 'YouTube': html = re.sub(r'feature=oembed', 'feature=oembed&showinfo=0', html) elif embed.provider_name == 'Vimeo': # We can't get rid of all of the Vimeo chrome, but this does as much as we can. html = re.sub( r'player\.vimeo\.com/video/(\d+)', r'player.vimeo.com/video/\1?title=0&byline=0&portrait=0', html) return mark_safe(html) except EmbedException: # Silently ignore failed embeds, rather than letting them crash the page. return ''
def test_invalid_width(self): embed = get_embed('www.test.com/1234', max_width=400, finder=self.dummy_finder_invalid_width) # Width must be set to None self.assertEqual(embed.width, None)
def create(self, value): isSignTranslate = value['variant'] == 'signtranslate' autoplay = isSignTranslate useThumbnail = isSignTranslate embed = get_embed(value["url"]) html = embed.html min_width = 400 if embed.width < min_width: original_width = embed.width original_height = embed.height original_ratio = embed.ratio embed.width = min_width embed.height = int(min_width * original_ratio) html = html.replace('width="%s"' % original_width, 'width="300"') html = html.replace('height="%s"' % original_height, 'height="%s"' % embed.height) if autoplay: html = html.replace("feature=oembed", "feature=oembed&autoplay=1") return { 'html': html, 'thubmnail': embed.thumbnail_url, 'width': embed.width, 'height': embed.height, 'title': embed.title, 'useThumbnail': useThumbnail }
def get_embed_video(self): try: if self.video_url.strip(): embed = get_embed(self.video_url) return embed.url except EmbedException: return self.video_url + 'Something went wrong while embeding the video! Invalid or not existing video URL!'
def thumbnail_url(self): from wagtail.embeds import embeds use_as_hero = self.get('use_as_hero') if not use_as_hero: return None embed = self.get('embed') return embeds.get_embed(embed.url).thumbnail_url
def test_invalid_width(self): embed = get_embed("www.test.com/1234", max_width=400, finder=self.dummy_finder_invalid_width) # Width must be set to None self.assertIsNone(embed.width)
def get_embed(embed_url): try: embed = embeds.get_embed(embed_url) return embed except EmbedException: # silently ignore failed embeds, rather than letting them crash the page return ""
def embed_to_editor_html(url): embed = embeds.get_embed(url) # catching EmbedException is the responsibility of the caller # Render template return render_to_string('wagtailembeds/embed_editor.html', { 'embed': embed, })
def fetch_from_url(self, url): embed = embeds.get_embed(url) return { "html": self._add_title_to_iframe(embed), "url": url, "ratio": embed.ratio, }
def test_get_embed_nonresponsive(self): embed = get_embed('www.test.com/1234', max_width=400, finder=self.dummy_finder) # Check that the embed is correct self.assertEqual(embed.title, "Test: www.test.com/1234") self.assertEqual(embed.type, 'video') self.assertEqual(embed.width, 400) self.assertFalse(embed.is_responsive)
def get_context(self, value, parent_context={}): context = super().get_context(value, parent_context=parent_context) embed_url = getattr(value, 'url', None) if embed_url: embed = embeds.get_embed(embed_url) context['embed_html'] = embed.html context['embed_url'] = embed_url context['ratio'] = embed.ratio return context
def get_api_representation(self, value, context=None): super().get_api_representation(value, context) try: embed = get_embed(self.get_prep_value(value)) return embed.html except EmbedException: # Cannot find embed pass return super().get_api_representation()
def get_context(self, value, parent_context={}): context = super().get_context(value, parent_context=parent_context) embed_url = getattr(value, "url", None) if embed_url: embed = embeds.get_embed(embed_url) context["embed_html"] = self._add_title_to_iframe(embed) context["embed_url"] = embed_url context["ratio"] = embed.ratio return context
def embed_to_frontend_html(url): try: embed = embeds.get_embed(url) # Render template return render_to_string('wagtailembeds/embed_frontend.html', { 'embed': embed, }) except EmbedException: # silently ignore failed embeds, rather than letting them crash the page return ''
def test_no_html(self): def no_html_finder(url, max_width=None): """ A finder which returns everything but HTML """ embed = self.dummy_finder(url, max_width) embed['html'] = None return embed embed = get_embed('www.test.com/1234', max_width=400, finder=no_html_finder) self.assertEqual(embed.html, '')
def chooser_upload(request): if request.method == 'POST': form = EmbedForm(request.POST, request.FILES, prefix='embed-chooser') if form.is_valid(): error = None try: embed_html = embed_to_editor_html(form.cleaned_data['url']) embed_obj = embeds.get_embed(form.cleaned_data['url']) embed_data = { 'embedType': embed_obj.type, 'url': embed_obj.url, 'providerName': embed_obj.provider_name, 'authorName': embed_obj.author_name, 'thumbnail': embed_obj.thumbnail_url, 'title': embed_obj.title, } return render_modal_workflow(request, None, None, None, json_data={ 'step': 'embed_chosen', 'embed_html': embed_html, 'embed_data': embed_data }) except AccessDeniedEmbedlyException: error = _( "There seems to be a problem with your embedly API key. Please check your settings." ) except (EmbedNotFoundException, EmbedUnsupportedProviderException): error = _("Cannot find an embed for this URL.") except EmbedlyException: error = _( "There seems to be an error with Embedly while trying to embed this URL." " Please try again later.") if error: errors = form._errors.setdefault('url', ErrorList()) errors.append(error) return render_modal_workflow( request, 'wagtailembeds/chooser/chooser.html', None, {'form': form}, json_data={'step': 'chooser'}) else: form = EmbedForm(prefix='embed-chooser') return render_modal_workflow(request, 'wagtailembeds/chooser/chooser.html', None, {'form': form}, json_data={'step': 'chooser'})
def parse_media_blocks(media_urls): media_blocks = [] for url in media_urls.split(", "): domain = urlparse(url).netloc if domain in ["vimeo.com", "www.youtube.com"]: embed = get_embed(url) embed_tuple = ("embed", embed) media_blocks.append(embed_tuple) else: # The default should be to fetch a PDF or image file (i.e. from westernfriend.org) response = requests.get(url) content_type = response.headers["content-type"] file_name = url.split("/")[-1] file_bytes = BytesIO(response.content) if content_type == "application/pdf": # Create file document_file = File(file_bytes, name=file_name) document = Document( title=file_name, file=document_file, ) document.save() document_link_block = ("document", document) media_blocks.append(document_link_block) elif content_type in ["image/jpeg", "image/png"]: # create image image_file = ImageFile(file_bytes, name=file_name) image = Image( title=file_name, file=image_file, ) image.save() image_block = ("image", image) media_blocks.append(image_block) else: print(url) print(content_type) print("-----") return media_blocks
def embed_to_frontend_html(url, max_width=None, max_height=None): try: embed = embeds.get_embed(url, max_width, max_height) # Render template return render_to_string( "wagtailembeds/embed_frontend.html", { "embed": embed, }, ) except EmbedException: # silently ignore failed embeds, rather than letting them crash the page return ""
def create_entity(self, name, attrs, state, contentstate): try: embed_obj = embeds.get_embed(attrs['url']) embed_data = { 'embedType': embed_obj.type, 'url': embed_obj.url, 'providerName': embed_obj.provider_name, 'authorName': embed_obj.author_name, 'thumbnail': embed_obj.thumbnail_url, 'title': embed_obj.title, } except EmbedException: embed_data = {'url': attrs['url']} return Entity('EMBED', 'IMMUTABLE', embed_data)
def create_entity(self, name, attrs, state, contentstate): try: embed_obj = embeds.get_embed(attrs["url"]) embed_data = { "embedType": embed_obj.type, "url": embed_obj.url, "providerName": embed_obj.provider_name, "authorName": embed_obj.author_name, "thumbnail": embed_obj.thumbnail_url, "title": embed_obj.title, } except EmbedException: embed_data = {"url": attrs["url"]} return Entity("EMBED", "IMMUTABLE", embed_data)
def create_entity(self, name, attrs, state, contentstate): try: embed_obj = embeds.get_embed(attrs['url']) embed_data = { 'embedType': embed_obj.type, 'url': embed_obj.url, 'providerName': embed_obj.provider_name, 'authorName': embed_obj.author_name, 'thumbnail': embed_obj.thumbnail_url, 'title': embed_obj.title, } except EmbedException: embed_data = {'url': attrs['url']} return Entity('EMBED', 'IMMUTABLE', embed_data)
def embed_to_frontend_html(url): try: embed = embeds.get_embed(url) embed.html = embed.html.replace("feature=oembed", "feature=oembed&autoplay=1") add = 'data-thumbnail="%s"' % embed.thumbnail_url add += ' data-title="%s"' % embed.title embed.html = embed.html.replace(" src=", "%s src=" % add) # Render template return render_to_string('wagtailembeds/embed_frontend.html', { 'embed': embed, }) except EmbedException: # silently ignore failed embeds, rather than letting them crash the page return ''
def chooser_upload(request): if request.method == 'POST': form = EmbedForm(request.POST, request.FILES, prefix='embed-chooser') if form.is_valid(): error = None try: embed_html = embed_to_editor_html(form.cleaned_data['url']) embed_obj = embeds.get_embed(form.cleaned_data['url']) embed_data = { 'embedType': embed_obj.type, 'url': embed_obj.url, 'providerName': embed_obj.provider_name, 'authorName': embed_obj.author_name, 'thumbnail': embed_obj.thumbnail_url, 'title': embed_obj.title, } return render_modal_workflow( request, None, None, None, json_data={'step': 'embed_chosen', 'embed_html': embed_html, 'embed_data': embed_data} ) except AccessDeniedEmbedlyException: error = _("There seems to be a problem with your embedly API key. Please check your settings.") except (EmbedNotFoundException, EmbedUnsupportedProviderException): error = _("Cannot find an embed for this URL.") except EmbedlyException: error = _( "There seems to be an error with Embedly while trying to embed this URL." " Please try again later." ) if error: errors = form._errors.setdefault('url', ErrorList()) errors.append(error) return render_modal_workflow( request, 'wagtailembeds/chooser/chooser.html', None, {'form': form}, json_data={'step': 'chooser'} ) else: form = EmbedForm(prefix='embed-chooser') return render_modal_workflow( request, 'wagtailembeds/chooser/chooser.html', None, {'form': form}, json_data={'step': 'chooser'} )
def oembed(url): try: embed = embeds.get_embed(url) # Work out ratio if embed.width and embed.height: ratio = str(embed.height / embed.width * 100) + "%" else: ratio = "0" # Render template return render_to_string('wagtailembeds/embed_frontend.html', { 'embed': embed, 'ratio': ratio, }) except EmbedException: # silently ignore failed embeds, rather than letting them crash the page return ''
def clean(self): errors = defaultdict(list) if self.hero_video and not self.hero_video_preview_image: errors["hero_video_preview_image"].append( "Please add a preview image for the video.") if self.programme_details_credits and not self.programme_details_credits_suffix: errors["programme_details_credits_suffix"].append( "Please add a suffix") if self.programme_details_credits_suffix and not self.programme_details_credits: errors["programme_details_credits"].append( "Please add a credit value") if self.programme_details_time and not self.programme_details_time_suffix: errors["programme_details_time_suffix"].append( "Please add a suffix") if self.programme_details_time_suffix and not self.programme_details_time: errors["programme_details_time"].append("Please add a time value") if self.curriculum_video: try: embed = embeds.get_embed(self.curriculum_video) except EmbedException: errors["curriculum_video"].append("invalid embed URL") else: if embed.provider_name.lower() != "youtube": errors["curriculum_video"].append( "Only YouTube videos are supported for this field ") if self.staff_link and not self.staff_link_text: errors["staff_link_text"].append( "Please the text to be used for the link") if self.staff_link_text and not self.staff_link: errors["staff_link_text"].append( "Please add a URL value for the link") if not self.contact_email and not self.contact_url: errors["contact_url"].append( "Please add a target value for the contact us link") if self.contact_email and self.contact_url: errors["contact_url"].append( "Only one of URL or an Email value is supported here") if not self.search_description: errors["search_description"].append( "Please add a search description for the page.") if errors: raise ValidationError(errors)
def serialize_block_value(self, block, value): if isinstance(value, str): return value if isinstance(value, RichText): return convert_rich_text(value.source, self.request, self.absolute_urls) if isinstance(value, get_image_model()): rendition = value.get_rendition(self.rendition_filter) return { 'id': value.id, 'url': resolve_absolute_url(rendition.url, self.request, absolute=self.absolute_urls is True), 'title': value.title, 'alt': rendition.alt, } if isinstance(value, StructValue): return collections.OrderedDict(self.serialize_struct_block(value)) if isinstance(value, EmbedValue): embed = get_embed(value.url) return { 'id': embed.id, 'html': embed.html, 'url': value.url, } if isinstance(block, ListBlock): return tuple(self.serialize_list_block(block, value)) raise RuntimeError( f'Cannot serialize StreamField value of type "{type(value)}"')
def test_no_finders_available(self): with self.assertRaises(EmbedUnsupportedProviderException): get_embed('www.test.com/1234', max_width=400)
def embed_tag(url, max_width=None): try: embed = embeds.get_embed(url, max_width=max_width) return mark_safe(embed.html) except EmbedException: return ''
def get_embed_object(instance): try: return get_embed(get_embed_url(instance)) except EmbedException: pass
def test_invalid_width(self): embed = get_embed('www.test.com/1234', max_width=400, finder=self.dummy_finder_invalid_width) # Width must be set to None self.assertEqual(embed.width, None)
def test_no_finders_available(self): with self.assertRaises(EmbedUnsupportedProviderException): get_embed('www.test.com/1234', max_width=400)