kopia lustrzana https://github.com/wagtail/wagtail
				
				
				
			fix small youtube embed - allow to override max_width/max_height in EmbedBlock
							rodzic
							
								
									a64eb1f2f3
								
							
						
					
					
						commit
						50e4f5151d
					
				| 
						 | 
				
			
			@ -10,6 +10,7 @@ Changelog
 | 
			
		|||
 * Added `full_url` property to image renditions (Shreyash Srivastava)
 | 
			
		||||
 * Added locale selector when choosing translatable snippets (Karl Hobley)
 | 
			
		||||
 * Added `WAGTAIL_WORKFLOW_ENABLED` setting for enabling / disabling moderation workflows globally (Matt Westcott)
 | 
			
		||||
 * Allow specifying `max_width` and `max_height` on EmbedBlock (Petr Dlouhý)
 | 
			
		||||
 * Fix: Invalid filter values for foreign key fields in the API now give an error instead of crashing (Tidjani Dia)
 | 
			
		||||
 * Fix: Ordering specified in `construct_explorer_page_queryset` hook is now taken into account again by the page explorer API (Andre Fonseca)
 | 
			
		||||
 * Fix: Deleting a page from its listing view no longer results in a 404 error (Tidjani Dia)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,6 +33,8 @@ nest the embed code.
 | 
			
		|||
The :class:`~wagtail.embeds.block.EmbedBlock` block type allows embeds
 | 
			
		||||
to be placed into a ``StreamField``.
 | 
			
		||||
 | 
			
		||||
The ``max_width`` and ``max_height`` arguments are sent to the provider when fetching the embed code.
 | 
			
		||||
 | 
			
		||||
For example:
 | 
			
		||||
 | 
			
		||||
.. code-block:: python
 | 
			
		||||
| 
						 | 
				
			
			@ -42,7 +44,7 @@ For example:
 | 
			
		|||
    class MyStreamField(blocks.StreamBlock):
 | 
			
		||||
        ...
 | 
			
		||||
 | 
			
		||||
        embed = EmbedBlock()
 | 
			
		||||
        embed = EmbedBlock(max_width=800, max_height=400)
 | 
			
		||||
 | 
			
		||||
``{% embed %}`` tag
 | 
			
		||||
-------------------
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -332,6 +332,8 @@ Field block types
 | 
			
		|||
   A field for the editor to enter a URL to a media item (such as a YouTube video) to appear as embedded media on the page. The following keyword arguments are accepted in addition to the standard ones:
 | 
			
		||||
 | 
			
		||||
   :param required: If true (the default), the field cannot be left blank.
 | 
			
		||||
   :param max_width: The maximum width of the embed, in pixels; this will be passed to the provider when requesting the embed.
 | 
			
		||||
   :param max_height: The maximum height of the embed, in pixels; this will be passed to the provider when requesting the embed.
 | 
			
		||||
   :param max_length: The maximum allowed length of the field.
 | 
			
		||||
   :param min_length: The minimum allowed length of the field.
 | 
			
		||||
   :param help_text: Help text to display alongside the field.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,6 +18,7 @@ Other features
 | 
			
		|||
 * Added ``full_url`` property to image renditions (Shreyash Srivastava)
 | 
			
		||||
 * Added locale selector when choosing translatable snippets (Karl Hobley)
 | 
			
		||||
 * Added ``WAGTAIL_WORKFLOW_ENABLED`` setting for enabling / disabling moderation workflows globally (Matt Westcott)
 | 
			
		||||
 * Allow specifying ``max_width`` and ``max_height`` on EmbedBlock (Petr Dlouhý)
 | 
			
		||||
 | 
			
		||||
Bug fixes
 | 
			
		||||
~~~~~~~~~
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,12 +14,14 @@ class EmbedValue:
 | 
			
		|||
    we want to be able to do {% embed value.url 500 %} without
 | 
			
		||||
    doing a redundant fetch of the embed at the default width.
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self, url):
 | 
			
		||||
    def __init__(self, url, max_width=None, max_height=None):
 | 
			
		||||
        self.url = url
 | 
			
		||||
        self.max_width = max_width
 | 
			
		||||
        self.max_height = max_height
 | 
			
		||||
 | 
			
		||||
    @cached_property
 | 
			
		||||
    def html(self):
 | 
			
		||||
        return embed_to_frontend_html(self.url)
 | 
			
		||||
        return embed_to_frontend_html(self.url, self.max_width, self.max_height)
 | 
			
		||||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return self.html
 | 
			
		||||
| 
						 | 
				
			
			@ -34,7 +36,7 @@ class EmbedBlock(blocks.URLBlock):
 | 
			
		|||
            return self.meta.default
 | 
			
		||||
        else:
 | 
			
		||||
            # assume default has been passed as a string
 | 
			
		||||
            return EmbedValue(self.meta.default)
 | 
			
		||||
            return EmbedValue(self.meta.default, getattr(self.meta, 'max_width', None), getattr(self.meta, 'max_height', None))
 | 
			
		||||
 | 
			
		||||
    def to_python(self, value):
 | 
			
		||||
        # The JSON representation of an EmbedBlock's value is a URL string;
 | 
			
		||||
| 
						 | 
				
			
			@ -42,7 +44,7 @@ class EmbedBlock(blocks.URLBlock):
 | 
			
		|||
        if not value:
 | 
			
		||||
            return None
 | 
			
		||||
        else:
 | 
			
		||||
            return EmbedValue(value)
 | 
			
		||||
            return EmbedValue(value, getattr(self.meta, 'max_width', None), getattr(self.meta, 'max_height', None))
 | 
			
		||||
 | 
			
		||||
    def get_prep_value(self, value):
 | 
			
		||||
        # serialisable value should be a URL string
 | 
			
		||||
| 
						 | 
				
			
			@ -63,7 +65,7 @@ class EmbedBlock(blocks.URLBlock):
 | 
			
		|||
        if not value:
 | 
			
		||||
            return None
 | 
			
		||||
        else:
 | 
			
		||||
            return EmbedValue(value)
 | 
			
		||||
            return EmbedValue(value, getattr(self.meta, 'max_width', None), getattr(self.meta, 'max_height', None))
 | 
			
		||||
 | 
			
		||||
    def clean(self, value):
 | 
			
		||||
        if isinstance(value, EmbedValue) and not value.html:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,13 +3,14 @@ from hashlib import md5
 | 
			
		|||
 | 
			
		||||
from django.utils.timezone import now
 | 
			
		||||
 | 
			
		||||
from ..core.utils import accepts_kwarg
 | 
			
		||||
from .exceptions import EmbedUnsupportedProviderException
 | 
			
		||||
from .finders import get_finders
 | 
			
		||||
from .models import Embed
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_embed(url, max_width=None, finder=None):
 | 
			
		||||
    embed_hash = get_embed_hash(url, max_width)
 | 
			
		||||
def get_embed(url, max_width=None, max_height=None, finder=None):
 | 
			
		||||
    embed_hash = get_embed_hash(url, max_width, max_height)
 | 
			
		||||
 | 
			
		||||
    # Check database
 | 
			
		||||
    try:
 | 
			
		||||
| 
						 | 
				
			
			@ -20,14 +21,17 @@ def get_embed(url, max_width=None, finder=None):
 | 
			
		|||
    # Get/Call finder
 | 
			
		||||
    if not finder:
 | 
			
		||||
 | 
			
		||||
        def finder(url, max_width=None):
 | 
			
		||||
        def finder(url, max_width=None, max_height=None):
 | 
			
		||||
            for finder in get_finders():
 | 
			
		||||
                if finder.accept(url):
 | 
			
		||||
                    return finder.find_embed(url, max_width=max_width)
 | 
			
		||||
                    kwargs = {}
 | 
			
		||||
                    if accepts_kwarg(finder.find_embed, 'max_height'):
 | 
			
		||||
                        kwargs['max_height'] = max_height
 | 
			
		||||
                    return finder.find_embed(url, max_width=max_width, **kwargs)
 | 
			
		||||
 | 
			
		||||
            raise EmbedUnsupportedProviderException
 | 
			
		||||
 | 
			
		||||
    embed_dict = finder(url, max_width)
 | 
			
		||||
    embed_dict = finder(url, max_width, max_height)
 | 
			
		||||
 | 
			
		||||
    # Make sure width and height are valid integers before inserting into database
 | 
			
		||||
    try:
 | 
			
		||||
| 
						 | 
				
			
			@ -65,10 +69,13 @@ def get_embed(url, max_width=None, finder=None):
 | 
			
		|||
    return embed
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_embed_hash(url, max_width=None):
 | 
			
		||||
def get_embed_hash(url, max_width=None, max_height=None):
 | 
			
		||||
    h = md5()
 | 
			
		||||
    h.update(url.encode("utf-8"))
 | 
			
		||||
    if max_width is not None:
 | 
			
		||||
        h.update(b"\n")
 | 
			
		||||
        h.update(str(max_width).encode("utf-8"))
 | 
			
		||||
    if max_height is not None:
 | 
			
		||||
        h.update(b"\n")
 | 
			
		||||
        h.update(str(max_height).encode("utf-8"))
 | 
			
		||||
    return h.hexdigest()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,7 +45,7 @@ class OEmbedFinder(EmbedFinder):
 | 
			
		|||
    def accept(self, url):
 | 
			
		||||
        return self._get_endpoint(url) is not None
 | 
			
		||||
 | 
			
		||||
    def find_embed(self, url, max_width=None):
 | 
			
		||||
    def find_embed(self, url, max_width=None, max_height=None):
 | 
			
		||||
        # Find provider
 | 
			
		||||
        endpoint = self._get_endpoint(url)
 | 
			
		||||
        if endpoint is None:
 | 
			
		||||
| 
						 | 
				
			
			@ -57,6 +57,8 @@ class OEmbedFinder(EmbedFinder):
 | 
			
		|||
        params['format'] = 'json'
 | 
			
		||||
        if max_width:
 | 
			
		||||
            params['maxwidth'] = max_width
 | 
			
		||||
        if max_height:
 | 
			
		||||
            params['maxheight'] = max_height
 | 
			
		||||
 | 
			
		||||
        # Perform request
 | 
			
		||||
        request = Request(endpoint + '?' + urlencode(params))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,9 +4,9 @@ from wagtail.embeds import embeds
 | 
			
		|||
from wagtail.embeds.exceptions import EmbedException
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def embed_to_frontend_html(url):
 | 
			
		||||
def embed_to_frontend_html(url, max_width=None, max_height=None):
 | 
			
		||||
    try:
 | 
			
		||||
        embed = embeds.get_embed(url)
 | 
			
		||||
        embed = embeds.get_embed(url, max_width, max_height)
 | 
			
		||||
 | 
			
		||||
        # Render template
 | 
			
		||||
        return render_to_string('wagtailembeds/embed_frontend.html', {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -122,7 +122,7 @@ class TestEmbeds(TestCase):
 | 
			
		|||
    def setUp(self):
 | 
			
		||||
        self.hit_count = 0
 | 
			
		||||
 | 
			
		||||
    def dummy_finder(self, url, max_width=None):
 | 
			
		||||
    def dummy_finder(self, url, max_width=None, max_height=None):
 | 
			
		||||
        # Up hit count
 | 
			
		||||
        self.hit_count += 1
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -175,7 +175,7 @@ class TestEmbeds(TestCase):
 | 
			
		|||
        self.assertFalse(embed.is_responsive)
 | 
			
		||||
        self.assertIsNone(embed.cache_until)
 | 
			
		||||
 | 
			
		||||
    def dummy_cache_until_finder(self, url, max_width=None):
 | 
			
		||||
    def dummy_cache_until_finder(self, url, max_width=None, max_height=None):
 | 
			
		||||
        # Up hit count
 | 
			
		||||
        self.hit_count += 1
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -210,7 +210,7 @@ class TestEmbeds(TestCase):
 | 
			
		|||
        self.assertEqual(embed, embed_3)
 | 
			
		||||
        self.assertEqual(embed_3.cache_until, future_dt)
 | 
			
		||||
 | 
			
		||||
    def dummy_finder_invalid_width(self, url, max_width=None):
 | 
			
		||||
    def dummy_finder_invalid_width(self, url, max_width=None, max_height=None):
 | 
			
		||||
        # Return a record with an invalid width
 | 
			
		||||
        return {
 | 
			
		||||
            'title': "Test: " + url,
 | 
			
		||||
| 
						 | 
				
			
			@ -228,7 +228,7 @@ class TestEmbeds(TestCase):
 | 
			
		|||
        self.assertEqual(embed.width, None)
 | 
			
		||||
 | 
			
		||||
    def test_no_html(self):
 | 
			
		||||
        def no_html_finder(url, max_width=None):
 | 
			
		||||
        def no_html_finder(url, max_width=None, max_height=None):
 | 
			
		||||
            """
 | 
			
		||||
            A finder which returns everything but HTML
 | 
			
		||||
            """
 | 
			
		||||
| 
						 | 
				
			
			@ -710,7 +710,7 @@ class TestEmbedBlock(TestCase):
 | 
			
		|||
        self.assertIn('<h1>Hello world!</h1>', result)
 | 
			
		||||
 | 
			
		||||
        # Check that get_embed was called correctly
 | 
			
		||||
        get_embed.assert_any_call('http://www.example.com/foo')
 | 
			
		||||
        get_embed.assert_any_call('http://www.example.com/foo', None, None)
 | 
			
		||||
 | 
			
		||||
    @patch('wagtail.embeds.embeds.get_embed')
 | 
			
		||||
    def test_render_within_structblock(self, get_embed):
 | 
			
		||||
| 
						 | 
				
			
			@ -735,7 +735,7 @@ class TestEmbedBlock(TestCase):
 | 
			
		|||
        self.assertIn('<h1>Hello world!</h1>', result)
 | 
			
		||||
 | 
			
		||||
        # Check that get_embed was called correctly
 | 
			
		||||
        get_embed.assert_any_call('http://www.example.com/foo')
 | 
			
		||||
        get_embed.assert_any_call('http://www.example.com/foo', None, None)
 | 
			
		||||
 | 
			
		||||
    def test_value_from_form(self):
 | 
			
		||||
        """
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -129,4 +129,4 @@ class TestFrontendMediaEmbedHandler(TestCase):
 | 
			
		|||
 | 
			
		||||
        result = expand_db_html('<p>1 2 <embed embedtype="media" url="https://www.youtube.com/watch?v=O7D-1RG-VRk&t=25" /> 3 4</p>')
 | 
			
		||||
        self.assertIn('test html', result)
 | 
			
		||||
        get_embed.assert_called_with('https://www.youtube.com/watch?v=O7D-1RG-VRk&t=25')
 | 
			
		||||
        get_embed.assert_called_with('https://www.youtube.com/watch?v=O7D-1RG-VRk&t=25', None, None)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Ładowanie…
	
		Reference in New Issue