Source code for embed_video.backends

import re
import requests
import json

try:
    import urlparse  # py2
except:
    import urllib.parse as urlparse  # py3


from .utils import import_by_path
from .settings import EMBED_VIDEO_BACKENDS, EMBED_VIDEO_CACHE, \
                      EMBED_VIDEO_CACHE_TIMEOUT

cache = None
if EMBED_VIDEO_CACHE:
    from django.core.cache import cache


class VideoDoesntExistException(Exception):
    pass


class UnknownBackendException(Exception):
    pass


class UnknownIdException(Exception):
    pass


[docs]def detect_backend(url): """ Detect the right backend for given URL. """ for backend_name in EMBED_VIDEO_BACKENDS: backend = import_by_path(backend_name) if backend.is_valid(url): return backend(url) raise UnknownBackendException
[docs]class VideoBackend(object): """ Base backend, good to inherit. """ re_code = None """ Compiled regex (:py:func:`re.compile`) to search code in URL. Example: ``re.compile(r'myvideo\.com/\?code=(?P<code>\w+)')`` """ re_detect = None """ Compilede regec (:py:func:`re.compile`) to detect, if input URL is valid for current backend. Example: ``re.compile(r'^http://myvideo\.com/.*')`` """ pattern_url = None """ Pattern in which the code is inserted. Example: ``http://myvideo.com?code=%s`` """ pattern_thumbnail_url = None """ Pattern in which the code is inserted to get thumbnail url. Example: ``http://static.myvideo.com/thumbs/%s`` """ def __init__(self, url): """ First it tries to load data from cache and if it don't succeed, run :py:meth:`init` and then save it to cache. """ if not self._restore_cache(url): self.init(url) self._set_cache(url) def _restore_cache(self, url): """ Restore data from cache if cache is enabled. """ if cache: data = cache.get(url) if data: self.__dict__ = data return True def _set_cache(self, url): """ Set data to cache if cache is enabled. """ if cache: cache.set(url, self.__dict__)
[docs] def init(self, url): """ Load all data (:py:meth:`get_code`, :py:meth:`get_url` etc.) """ self._url = url self.backend = self.__class__.__name__ self.code = self.get_code() self.url = self.get_url() self.thumbnail = self.get_thumbnail_url()
@classmethod
[docs] def is_valid(klass, url): """ Class method to control if passed url is valid for current backend. By default it is done by :py:data:`re_detect` regex. """ return True if klass.re_detect.match(url) else False
[docs] def get_code(self): """ Returns searched code from URL by :py:data:`re_code`. """ match = self.re_code.search(self._url) if match: return match.group('code')
[docs] def get_url(self): """ Returns URL folded from :py:data:`pattern_url` and parsed code. """ return self.pattern_url % self.code
[docs] def get_thumbnail_url(self): """ Returns thumbnail URL folded from :py:data:`pattern_thumbnail_url` and parsed code. """ return self.pattern_thumbnail_url % self.code
[docs]class YoutubeBackend(VideoBackend): """ Backend for YouTube URLs. """ re_detect = re.compile( r'^(http(s)?://)?(www\.)?youtu(\.?)be(\.com)?/.*', re.I ) re_code = re.compile( r'''youtu(\.?)be(\.com)?/ # match youtube's domains (embed/)? # match the embed url syntax (v/)? (watch\?v=)? # match the youtube page url (ytscreeningroom\?v=)? (feeds/api/videos/)? (user\S*[^\w\-\s])? (\S*[^\w\-\s])? (?P<code>[\w\-]{11})[a-z0-9;:@?&%=+/\$_.-]* # match and extract ''', re.I | re.X ) 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
[docs]class VimeoBackend(VideoBackend): """ Backend for Vimeo URLs. """ re_detect = re.compile( r'^(http(s)?://)?(www\.)?(player\.)?vimeo\.com/.*', re.I ) re_code = re.compile(r'''vimeo\.com/(video/)?(?P<code>[0-9]+)''', re.I) pattern_url = 'http://player.vimeo.com/video/%s' pattern_info = 'http://vimeo.com/api/v2/video/%s.json' info = None def init(self, url): self._url = url self.code = self.get_code() self.info = self.get_info() super(VimeoBackend, self).init(url) def get_info(self): try: response = requests.get(self.pattern_info % self.code) return json.loads(response.text)[0] except ValueError: raise VideoDoesntExistException() def get_thumbnail_url(self): return self.info['thumbnail_large']
[docs]class SoundCloudBackend(VideoBackend): """ Backend for SoundCloud URLs. """ base_url = 'http://soundcloud.com/oembed' re_detect = re.compile(r'^(http(s)?://(www\.)?)?soundcloud\.com/.*', re.I) 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): params = { 'format': 'json', 'url': 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(SoundCloudBackend, self).init(url) def get_thumbnail_url(self): return self.response.get('thumbnail_url') def get_url(self): match = self.re_url.search(self.response.get('html')) return match.group('url') def get_code(self): match = self.re_code.search(self.response.get('html')) return match.group('code')

This Page