support for soundcloud

Little refactoring, apply PEP8 rules, some tests
This commit is contained in:
Juda Kaleta 2013-06-25 10:51:44 +02:00
parent e798482f5a
commit 2ec28d6770
4 changed files with 67 additions and 40 deletions

View file

@ -1,18 +1,27 @@
import re
import urlparse
DETECT_YOUTUBE = re.compile(
'^(http(s)?://(www\.)?)?youtu(\.?)be(\.com)?.*', re.I
)
DETECT_VIMEO = re.compile('^(http(s)?://(www\.)?)?vimeo\.com.*', re.I)
DETECT_SOUNDCLOUD = re.compile('^(http(s)?://(www\.)?)?soundcloud\.com.*', re.I)
import requests
import json
DETECT_YOUTUBE = re.compile(
r'^(http(s)?://(www\.)?)?youtu(\.?)be(\.com)?.*', re.I
)
DETECT_VIMEO = re.compile(
r'^(http(s)?://(www\.)?)?vimeo\.com.*', re.I
)
DETECT_SOUNDCLOUD = re.compile(
r'^(http(s)?://(www\.)?)?soundcloud\.com.*', re.I
)
class UnknownBackendException(Exception):
pass
class NoIdVideoFound(Exception):
class NoIdFound(Exception):
pass
def detect_backend(url):
if DETECT_YOUTUBE.match(url):
return YoutubeBackend(url)
@ -39,10 +48,10 @@ class VideoBackend(object):
else:
parse_data = urlparse.urlparse(self._url)
try:
return urlparse.parse_qs(parse_data.query)["v"][0]
return urlparse.parse_qs(parse_data.query)['v'][0]
except KeyError:
pass
raise NoIdVideoFound
raise NoIdFound
def get_url(self):
return self.pattern_url % self.code
@ -52,38 +61,40 @@ class VideoBackend(object):
class SoundCloundBackend(VideoBackend):
_base_url = "http://soundcloud.com/oembed"
url = None
base_url = 'http://soundcloud.com/oembed'
re_code = re.compile(r'src=".*%2F(?P<code>\d+)&show_artwork.*"', re.I)
re_url = re.compile(r'src="(?P<url>.*?)"', re.I)
def __init__(self, url):
import requests
params = {
'format':'json',
'format': 'json',
'url': url,
}
r = requests.get(self._base_url, data=params)
json_response = json.loads(r.text)
self._response = json_response
self.thumbnail = json_response.get("thumbnail_url")
match = re.search(r'src="(.*?)"', json_response.get("html"))
if match:
self.url = match.groups()[0]
self.width = json_response.get("width")
self.height = json_response.get("height")
super(SoundCloundBackend,self).__init__(url)
r = requests.get(self.base_url, data=params)
self.response = json.loads(r.text)
self.width = self.response.get('width')
self.height = self.response.get('height')
super(SoundCloundBackend, self).__init__(url)
def get_thumbnail_url(self):
return self.thumbnail
return self.response.get('thumbnail_url')
def get_url(self):
return self.url
match = self.re_url.search(self.response.get('html'))
return match.group('url')
def get_code(self):
return self.url
match = self.re_code.search(self.response.get('html'))
return match.group('code')
class YoutubeBackend(VideoBackend):
re_code = re.compile(
'youtu(?:be\.com/watch\?v=|\.be/)(?P<code>[\w-]*)(&(amp;)?[\w\?=]*)?',
r'youtu(?:be\.com/watch\?v=|\.be/)(?P<code>[\w-]*)(&(amp;)?[\w\?=]*)?',
re.I
)
pattern_url = 'http://www.youtube.com/embed/%s?wmode=opaque'
@ -91,7 +102,7 @@ class YoutubeBackend(VideoBackend):
class VimeoBackend(VideoBackend):
re_code = re.compile('vimeo\.com/(?P<code>[0-9]+)', re.I)
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):

View file

@ -2,7 +2,7 @@ from django.db import models
from django import forms
from django.utils.translation import ugettext_lazy as _
from .base import detect_backend, NoIdVideoFound, UnknownBackendException
from .base import detect_backend, NoIdFound, UnknownBackendException
__all__ = ('EmbedVideoField', 'EmbedVideoFormField')
@ -30,7 +30,7 @@ class EmbedVideoFormField(forms.URLField):
detect_backend(url)
except UnknownBackendException:
raise forms.ValidationError(_(u'URL could not be recognized.'))
except NoIdVideoFound:
except NoIdFound:
raise forms.ValidationError(_(u'Video Id not found .'))
return url

View file

@ -48,8 +48,6 @@ def embed(backend, _size='small'):
'huge': (1280, 960),
}
if _size in sizes:
size = sizes[_size]
elif 'x' in _size:
@ -60,10 +58,10 @@ def embed(backend, _size='small'):
'width': int(size[0]),
'height': int(size[1]),
}
if isinstance(backend,SoundCloundBackend):
# max height of soundcloud
params.update({'height':backend.height})
if isinstance(backend, SoundCloundBackend):
params.update({'height': backend.height})
return mark_safe(
'<iframe width="%(width)d" height="%(height)d" '
'src="%(url)s" frameborder="0" allowfullscreen>'

View file

@ -6,7 +6,8 @@ from django.http import HttpRequest
from django.template.base import Template
from django.template.context import RequestContext
from ..base import detect_backend, YoutubeBackend, VimeoBackend
from ..base import detect_backend, YoutubeBackend, VimeoBackend, \
SoundCloundBackend
os.environ['DJANGO_SETTINGS_MODULE'] = 'embed_video.tests.django_settings'
@ -27,6 +28,12 @@ class EmbedVideoTestCase(TestCase):
('http://www.vimeo.com/66577491', '66577491'),
)
soundcloud_urls = (
('https://soundcloud.com/glassnote/mumford-sons-i-will-wait', '67129237'),
('https://soundcloud.com/matej-roman/jaromir-nohavica-karel-plihal-mikymauz', '7834701'),
('https://soundcloud.com/beny97/sets/jaromir-nohavica-prazska', '960591'),
)
def setUp(self):
from django.conf import settings as django_settings
self.django_settings = django_settings
@ -88,6 +95,11 @@ class EmbedVideoTestCase(TestCase):
backend = detect_backend(url[0])
self.assertIsInstance(backend, VimeoBackend)
def test_detect_soundcloud(self):
for url in self.soundcloud_urls:
backend = detect_backend(url[0])
self.assertIsInstance(backend, SoundCloundBackend)
def test_code_youtube(self):
for url in self.youtube_urls:
backend = YoutubeBackend(url[0])
@ -100,6 +112,12 @@ class EmbedVideoTestCase(TestCase):
code = backend.get_code()
self.assertEqual(code, url[1])
def test_code_soundcloud(self):
for url in self.soundcloud_urls:
backend = SoundCloundBackend(url[0])
code = backend.get_code()
self.assertEqual(code, url[1])
if __name__ == '__main__':
main()