Skip to content

Commit

Permalink
Closes #5.
Browse files Browse the repository at this point in the history
Add {{ my_video.backend }} containing YoutubeBackend, VimeoBackend or SoundCloudBackend values.

- Fix: SoundClound --> SoundCloud
- added tests for template tags
  • Loading branch information
yetty committed Aug 20, 2013
1 parent d0d357b commit 08641af
Show file tree
Hide file tree
Showing 6 changed files with 189 additions and 116 deletions.
1 change: 1 addition & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ Usage of variables:
{% video item.video as my_video %}
URL: {{ my_video.url }}
Thumbnail: {{ my_video.thumbnail }}
Backend: {{ my_video.backend }}
{% endvideo %}


Expand Down
65 changes: 33 additions & 32 deletions embed_video/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def detect_backend(url):
elif DETECT_VIMEO.match(url):
return VimeoBackend(url)
elif DETECT_SOUNDCLOUD.match(url):
return SoundCloundBackend(url)
return SoundCloudBackend(url)
else:
raise UnknownBackendException

Expand All @@ -37,6 +37,7 @@ class VideoBackend(object):
def __init__(self, url):
self._url = url

self.backend = self.__class__.__name__
self.code = self.get_code()
self.url = self.get_url()
self.thumbnail = self.get_thumbnail_url()
Expand All @@ -53,7 +54,36 @@ def get_thumbnail_url(self):
return self.pattern_thumbnail_url % self.code


class SoundCloundBackend(VideoBackend):
class YoutubeBackend(VideoBackend):
re_code = re.compile(
r'youtu(?:be\.com/watch\?v=|\.be/)(?P<code>[\w-]*)(&(amp;)?[\w\?=]*)?',
re.I
)
pattern_url = 'http://www.youtube.com/embed/%s?wmode=opaque'
pattern_thumbnail_url = 'http://img.youtube.com/vi/%s/hqdefault.jpg'

def get_code(self):
code = super(YoutubeBackend, self).get_code()

if not code:
parse_data = urlparse.urlparse(self._url)
try:
code = urlparse.parse_qs(parse_data.query)['v'][0]
except KeyError:
raise UnknownIdException

return code


class VimeoBackend(VideoBackend):
re_code = re.compile(r'vimeo\.com/(?P<code>[0-9]+)', re.I)
pattern_url = 'http://player.vimeo.com/video/%s'

def get_thumbnail_url(self):
pass # not implemented


class SoundCloudBackend(VideoBackend):
base_url = 'http://soundcloud.com/oembed'

re_code = re.compile(r'src=".*%2F(?P<code>\d+)&show_artwork.*"', re.I)
Expand All @@ -71,7 +101,7 @@ def __init__(self, url):
self.width = self.response.get('width')
self.height = self.response.get('height')

super(SoundCloundBackend, self).__init__(url)
super(SoundCloudBackend, self).__init__(url)

def get_thumbnail_url(self):
return self.response.get('thumbnail_url')
Expand All @@ -83,32 +113,3 @@ def get_url(self):
def get_code(self):
match = self.re_code.search(self.response.get('html'))
return match.group('code')


class YoutubeBackend(VideoBackend):
re_code = re.compile(
r'youtu(?:be\.com/watch\?v=|\.be/)(?P<code>[\w-]*)(&(amp;)?[\w\?=]*)?',
re.I
)
pattern_url = 'http://www.youtube.com/embed/%s?wmode=opaque'
pattern_thumbnail_url = 'http://img.youtube.com/vi/%s/hqdefault.jpg'

def get_code(self):
code = super(YoutubeBackend, self).get_code()

if not code:
parse_data = urlparse.urlparse(self._url)
try:
code = urlparse.parse_qs(parse_data.query)['v'][0]
except KeyError:
raise UnknownIdException

return code


class VimeoBackend(VideoBackend):
re_code = re.compile(r'vimeo\.com/(?P<code>[0-9]+)', re.I)
pattern_url = 'http://player.vimeo.com/video/%s'

def get_thumbnail_url(self):
pass # not implemented
37 changes: 24 additions & 13 deletions embed_video/templatetags/embed_video_tags.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from django.template import Library, Node, TemplateSyntaxError
from django.utils.safestring import mark_safe, SafeText

from ..base import detect_backend, SoundCloundBackend
from ..base import detect_backend, SoundCloudBackend

register = Library()

Expand Down Expand Up @@ -43,6 +43,17 @@ def embed(backend, _size='small'):
if isinstance(backend, SafeText):
backend = detect_backend(backend)

size = _embed_get_size(_size)
params = _embed_get_params(backend, size)

return mark_safe(
'<iframe width="%(width)d" height="%(height)d" '
'src="%(url)s" frameborder="0" allowfullscreen>'
'</iframe>' % params
)


def _embed_get_size(size):
sizes = {
'tiny': (420, 315),
'small': (480, 360),
Expand All @@ -51,22 +62,22 @@ def embed(backend, _size='small'):
'huge': (1280, 960),
}

if _size in sizes:
size = sizes[_size]
elif 'x' in _size:
size = _size.split('x')
if size in sizes:
return sizes[size]
elif 'x' in size:
return [int(x) for x in size.split('x')]


def _embed_get_params(backend, size):
params = {
'url': backend.url,
'width': int(size[0]),
'height': int(size[1]),
'width': size[0],
'height': size[1],
}

if isinstance(backend, SoundCloundBackend):
if isinstance(backend, SoundCloudBackend):
params.update({'height': backend.height})

return mark_safe(
'<iframe width="%(width)d" height="%(height)d" '
'src="%(url)s" frameborder="0" allowfullscreen>'
'</iframe>' % params
)
return params


73 changes: 4 additions & 69 deletions embed_video/tests/tests_backend.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
from unittest import TestCase

from django.http import HttpRequest
from django.template.base import Template
from django.template.context import RequestContext

from ..base import detect_backend, YoutubeBackend, VimeoBackend, \
SoundCloundBackend, UnknownBackendException
SoundCloudBackend, UnknownBackendException


class EmbedVideoTestCase(TestCase):
Expand Down Expand Up @@ -43,70 +39,9 @@ def setUp(self):
from django.conf import settings as django_settings
self.django_settings = django_settings

def _grc(self):
return RequestContext(HttpRequest())

def test_embed(self):
template = Template("""
{% load embed_video_tags %}
{% video 'http://www.youtube.com/watch?v=jsrRJyHBvzw' as ytb %}
{{ ytb|embed:'large' }}
{% endvideo %}
""")
rendered = u'<iframe width="960" height="720" src="http://www.youtube.com/embed/jsrRJyHBvzw?wmode=opaque" frameborder="0" allowfullscreen></iframe>'

self.assertEqual(template.render(self._grc()).strip(), rendered)

def test_direct_embed(self):
template = Template("""
{% load embed_video_tags %}
{{ 'http://www.youtube.com/watch?v=jsrRJyHBvzw'|embed:'large' }}
""")
rendered = u'<iframe width="960" height="720" src="http://www.youtube.com/embed/jsrRJyHBvzw?wmode=opaque" frameborder="0" allowfullscreen></iframe>'

self.assertEqual(template.render(self._grc()).strip(), rendered)

def test_embed_user_size(self):
template = Template("""
{% load embed_video_tags %}
{% video 'http://www.youtube.com/watch?v=jsrRJyHBvzw' as ytb %}
{{ ytb|embed:'800x800' }}
{% endvideo %}
""")
rendered = u'<iframe width="800" height="800" src="http://www.youtube.com/embed/jsrRJyHBvzw?wmode=opaque" frameborder="0" allowfullscreen></iframe>'

self.assertEqual(template.render(self._grc()).strip(), rendered)

def test_tag_youtube(self):
template = Template("""
{% load embed_video_tags %}
{% video 'http://www.youtube.com/watch?v=jsrRJyHBvzw' as ytb %}
{{ ytb.url }}
{% endvideo %}
""")
rendered = 'http://www.youtube.com/embed/jsrRJyHBvzw?wmode=opaque'

self.assertEqual(template.render(self._grc()).strip(), rendered)

def test_tag_vimeo(self):
template = Template("""
{% load embed_video_tags %}
{% video 'https://vimeo.com/66577491' as vimeo %}
{{ vimeo.url }}
{% endvideo %}
""")
rendered = 'http://player.vimeo.com/video/66577491'

self.assertEqual(template.render(self._grc()).strip(), rendered)

def test_detect_bad_urls(self):
for url in self.unknown_backend_urls:
try:
backend = detect_backend(url)
self.assertEqual(backend, False)
except UnknownBackendException:
assert True

self.assertRaises(UnknownBackendException, detect_backend, url)

def test_detect_youtube(self):
for url in self.youtube_urls:
Expand All @@ -121,7 +56,7 @@ def test_detect_vimeo(self):
def test_detect_soundcloud(self):
for url in self.soundcloud_urls:
backend = detect_backend(url[0])
self.assertIsInstance(backend, SoundCloundBackend)
self.assertIsInstance(backend, SoundCloudBackend)

def test_code_youtube(self):
for url in self.youtube_urls:
Expand All @@ -137,6 +72,6 @@ def test_code_vimeo(self):

def test_code_soundcloud(self):
for url in self.soundcloud_urls:
backend = SoundCloundBackend(url[0])
backend = SoundCloudBackend(url[0])
code = backend.get_code()
self.assertEqual(code, url[1])
6 changes: 6 additions & 0 deletions embed_video/tests/tests_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,9 @@ def test_validation_unknownid(self):
mock_detect_backend.side_effect = UnknownIdException
self.assertRaises(ValidationError, self.formfield.validate,
('http://youtube.com/v/123/',))

def test_validation_correct(self):
url = 'http://my-testing.url.com'
with patch('embed_video.fields.detect_backend') as mock_detect_backend:
mock_detect_backend.return_value = True
self.assertEqual(url, self.formfield.validate(url))

0 comments on commit 08641af

Please sign in to comment.