<commit_before>"""
Uses the Noembed_ oEmbed service to embed (almost) arbitrary URLs.

Depends on requests_.
"""

from hashlib import md5

from django import forms
from django.core.cache import cache
from django.db import models
from django.utils.html import mark_safe
from django.utils.translation import ugettext, ugettext_lazy as _

import requests
from content_editor.admin import ContentEditorInline
from feincms3.utils import positional


__all__ = (
    'External', 'ExternalInline', 'oembed_json', 'oembed_html',
    'render_external',
)


@positional(1)
def oembed_json(url, cache_failures=True):
    """oembed_json(url, *, cache_failures=True)
    Asks Noembed_ for the embedding HTML code for arbitrary URLs. Sites
    supported include Youtube, Vimeo, Twitter and many others.

    Successful embeds are always cached for 30 days.

    Failures are cached if ``cache_failures`` is ``True`` (the default). The
    durations are as follows:

    - Connection errors are cached 60 seconds with the hope that the connection
      failure is only transient.
    - HTTP errors codes and responses in an unexpected format (no JSON) are
      cached for 24 hours.

    The return value is always a dictionary, but it may be empty.
    """
    # Thundering herd problem etc...
    key = 'oembed-url-%s-data' % md5(url.encode('utf-8')).hexdigest()
    data = cache.get(key)
    if data is not None:
        return data

    try:
        data = requests.get(
            'https://noembed.com/embed',
            params={
                'url': url,
                'nowrap': 'on',
                'maxwidth': 1200,
                'maxheight': 800,
            },
            timeout=2,
        ).json()
    except (requests.ConnectionError, requests.ReadTimeout):
        # Connection failed? Hopefully temporary, try again soon.
        timeout = 60
    except (ValueError, requests.HTTPError):
        # Oof... HTTP error code, or no JSON? Try again tomorrow,
        # and we should really log this.
        timeout = 86400
    else:
        # Perfect, cache for 30 days
        cache.set(key, data, timeout=30 * 86400)
        return data

    if cache_failures:
        cache.set(key, {}, timeout=timeout)
    return {}


@positional(1)
def oembed_html(url, cache_failures=True):
    """oembed_html(url, *, cache_failures=True)
    Wraps :func:`~feincms3.plugins.external.oembed_json`, but only returns
    the HTML part of the OEmbed response.

    The return value is always either a HTML fragment or an empty string.
    """
    return oembed_json(url, cache_failures=cache_failures).get('html', '')


def render_external(plugin, **kwargs):
    """
    Render the plugin, embedding it in the appropriate markup for Foundation's
    flex-video element (http://foundation.zurb.com/sites/docs/flex-video.html)
    """

    html = oembed_html(plugin.url)
    if 'youtube.com' in html:
        return mark_safe(
            '<div class="flex-video widescreen">{}</div>'.format(html))
    if 'vimeo.com' in html:
        return mark_safe(
            '<div class="flex-video widescreen vimeo">{}</div>'.format(html))
    return mark_safe(html)


class External(models.Model):
    """
    External content plugin
    """
    url = models.URLField(_('URL'))

    class Meta:
        abstract = True
        verbose_name = _('external content')
<commit_msg>replace flex-video to responsive-embed due to foundation update<commit_after>"""
Uses the Noembed_ oEmbed service to embed (almost) arbitrary URLs.

Depends on requests_.
"""

from hashlib import md5

from django import forms
from django.core.cache import cache
from django.db import models
from django.utils.html import mark_safe
from django.utils.translation import ugettext, ugettext_lazy as _

import requests
from content_editor.admin import ContentEditorInline
from feincms3.utils import positional


__all__ = (
    'External', 'ExternalInline', 'oembed_json', 'oembed_html',
    'render_external',
)


@positional(1)
def oembed_json(url, cache_failures=True):
    """oembed_json(url, *, cache_failures=True)
    Asks Noembed_ for the embedding HTML code for arbitrary URLs. Sites
    supported include Youtube, Vimeo, Twitter and many others.

    Successful embeds are always cached for 30 days.

    Failures are cached if ``cache_failures`` is ``True`` (the default). The
    durations are as follows:

    - Connection errors are cached 60 seconds with the hope that the connection
      failure is only transient.
    - HTTP errors codes and responses in an unexpected format (no JSON) are
      cached for 24 hours.

    The return value is always a dictionary, but it may be empty.
    """
    # Thundering herd problem etc...
    key = 'oembed-url-%s-data' % md5(url.encode('utf-8')).hexdigest()
    data = cache.get(key)
    if data is not None:
        return data

    try:
        data = requests.get(
            'https://noembed.com/embed',
            params={
                'url': url,
                'nowrap': 'on',
                'maxwidth': 1200,
                'maxheight': 800,
            },
            timeout=2,
        ).json()
    except (requests.ConnectionError, requests.ReadTimeout):
        # Connection failed? Hopefully temporary, try again soon.
        timeout = 60
    except (ValueError, requests.HTTPError):
        # Oof... HTTP error code, or no JSON? Try again tomorrow,
        # and we should really log this.
        timeout = 86400
    else:
        # Perfect, cache for 30 days
        cache.set(key, data, timeout=30 * 86400)
        return data

    if cache_failures:
        cache.set(key, {}, timeout=timeout)
    return {}


@positional(1)
def oembed_html(url, cache_failures=True):
    """oembed_html(url, *, cache_failures=True)
    Wraps :func:`~feincms3.plugins.external.oembed_json`, but only returns
    the HTML part of the OEmbed response.

    The return value is always either a HTML fragment or an empty string.
    """
    return oembed_json(url, cache_failures=cache_failures).get('html', '')


def render_external(plugin, **kwargs):
    """
    Render the plugin, embedding it in the appropriate markup for Foundation's
    responsive-embed element (https://foundation.zurb.com/sites/docs/responsive-embed.html)
    """

    html = oembed_html(plugin.url)
    if 'youtube.com' in html:
        return mark_safe(
            '<div class="responsive-embed widescreen">{}</div>'.format(html))
    if 'vimeo.com' in html:
        return mark_safe(
            '<div class="responsive-embed widescreen vimeo">{}</div>'.format(html))
    return mark_safe(html)


class External(models.Model):
    """
    External content plugin
    """
    url = models.URLField(_('URL'))

    class Meta:
        abstract = True
        verbose_name = _('external content')

{'fraction_non_alphanumeric': 0.10219408040053012, 'fraction_numerical': 0.010896775143572375, 'mean_word_length': 2.807174887892377, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 3, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7529886', 'n_tokens_mistral': 2053, 'n_tokens_neox': 1943, 'n_words': 639}