kopia lustrzana https://github.com/wagtail/wagtail
Make embedly optional and refactor code
This fixes #26. First of all there is some refactoring: All low level embed functions have been moved to the wagtail.wagtailembeds.embeds package. There you will see: . embed.py (which is more or less a copy of the old embeds.py) . oembed_api.py which includes some low level code for using embedding with the help of oembed, without any external dependencies (python-oembed was not working very well and since oembed is just a URL get to a specific URL I implemented it with urllib2 and json), . endpoints.json which is a list of oembed endpoints I got from https://github.com/panzi/oembedendpoints/blob/master/endpoints-regexp.json . unittests.py with some tests to check that well known sites like youtube, vimeo etc work fine with the oembed_api The code refactoring also includes a number of exceptions. The get_embed function now is included in try / except blocks and if an exception occurs then the output will be an emtpy string (this was the behavior before the refactor). However, in the chooser.py function the type of the exception will be checked and a nice message will be shown to the editor. Finally, to choose between embedly and the oembed a check is made to see if the embedly library has been installed and also check if EMBEDLY_KEY has been set in the settings. If these two checks are both true then the get_embed will be assigned to get_embed_embedly -- else it will be assigned to get_embed_oembed.pull/33/head
rodzic
0ddc5a6ff6
commit
74b9f43401
|
@ -52,7 +52,10 @@ class ImageEmbedHandler(object):
|
|||
format = get_image_format(attrs['format'])
|
||||
|
||||
if for_editor:
|
||||
return format.image_to_editor_html(image, attrs['alt'])
|
||||
try:
|
||||
return format.image_to_editor_html(image, attrs['alt'])
|
||||
except:
|
||||
return ''
|
||||
else:
|
||||
return format.image_to_html(image, attrs['alt'])
|
||||
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
from .models import Embed
|
||||
from .embeds import get_embed
|
||||
from .embeds.embed import get_embed
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
from datetime import datetime
|
||||
from django.conf import settings
|
||||
from ..models import Embed
|
||||
import oembed_api
|
||||
|
||||
class EmbedlyException(Exception): pass
|
||||
class AccessDeniedEmbedlyException(Exception): pass
|
||||
class NotFoundEmbedlyException(Exception): pass
|
||||
|
||||
def get_embed_embedly(url, max_width=None):
|
||||
# Check database
|
||||
try:
|
||||
return Embed.objects.get(url=url, max_width=max_width)
|
||||
except Embed.DoesNotExist:
|
||||
pass
|
||||
|
||||
client = Embedly(key=settings.EMBEDLY_KEY)
|
||||
|
||||
if max_width is not None:
|
||||
oembed = client.oembed(url, maxwidth=max_width, better=False)
|
||||
else:
|
||||
oembed = client.oembed(url, better=False)
|
||||
|
||||
# Check for error
|
||||
if oembed.get('error'):
|
||||
if oembed['error_code'] in [401,403]:
|
||||
raise AccessDeniedEmbedlyException
|
||||
elif oembed['error_code'] == 404:
|
||||
raise NotFoundEmbedlyException
|
||||
else:
|
||||
raise EmbedlyException
|
||||
|
||||
return save_embed(url, max_width, oembed)
|
||||
|
||||
|
||||
def get_embed_oembed(url, max_width=None):
|
||||
# Check database
|
||||
try:
|
||||
return Embed.objects.get(url=url, max_width=max_width)
|
||||
except Embed.DoesNotExist:
|
||||
pass
|
||||
|
||||
oembed = oembed_api.get_embed_oembed(url, max_width)
|
||||
return save_embed(url, max_width, oembed)
|
||||
|
||||
|
||||
def save_embed(url, max_width, oembed):
|
||||
row, created = Embed.objects.get_or_create(
|
||||
url=url,
|
||||
max_width=max_width,
|
||||
defaults={
|
||||
'type': oembed['type'],
|
||||
'title': oembed['title'],
|
||||
'thumbnail_url': oembed.get('thumbnail_url'),
|
||||
'width': oembed.get('width'),
|
||||
'height': oembed.get('height')
|
||||
}
|
||||
)
|
||||
|
||||
if oembed['type'] == 'photo':
|
||||
html = '<img src="%s" />' % (oembed['url'], )
|
||||
else:
|
||||
html = oembed.get('html')
|
||||
|
||||
if html:
|
||||
row.html = html
|
||||
row.last_updated = datetime.now()
|
||||
row.save()
|
||||
|
||||
return row
|
||||
|
||||
# As a default use oembed
|
||||
get_embed = get_embed_oembed
|
||||
try:
|
||||
from embedly import Embedly
|
||||
# if EMBEDLY_KEY is set and embedly library found the use embedly
|
||||
if hasattr(settings,'EMBEDLY_KEY'):
|
||||
get_embed = get_embed_embedly
|
||||
except:
|
||||
pass
|
|
@ -0,0 +1,295 @@
|
|||
{
|
||||
"https://speakerdeck.com/oembed.{format}": [
|
||||
"^http(?:s)?://speakerdeck\\.com/.+$"
|
||||
],
|
||||
"https://alpha-api.app.net/oembed": [
|
||||
"^http(?:s)?://alpha\\.app\\.net/[^#?/]+/post/.+$",
|
||||
"^http(?:s)?://photos\\.app\\.net/[^#?/]+/.+$"
|
||||
],
|
||||
"http://www.youtube.com/oembed": [
|
||||
"^http(?:s)?://(?:[-\\w]+\\.)?youtube\\.com/watch.+$",
|
||||
"^http(?:s)?://(?:[-\\w]+\\.)?youtube\\.com/v/.+$",
|
||||
"^http(?:s)?://youtu\\.be/.+$",
|
||||
"^http(?:s)?://(?:[-\\w]+\\.)?youtube\\.com/user/.+$",
|
||||
"^http(?:s)?://(?:[-\\w]+\\.)?youtube\\.com/[^#?/]+#[^#?/]+/.+$",
|
||||
"^http(?:s)?://m\\.youtube\\.com/index.+$",
|
||||
"^http(?:s)?://(?:[-\\w]+\\.)?youtube\\.com/profile.+$",
|
||||
"^http(?:s)?://(?:[-\\w]+\\.)?youtube\\.com/view_play_list.+$",
|
||||
"^http(?:s)?://(?:[-\\w]+\\.)?youtube\\.com/playlist.+$"
|
||||
],
|
||||
"http://backend.deviantart.com/oembed": [
|
||||
"^http://(?:[-\\w]+\\.)?deviantart\\.com/art/.+$",
|
||||
"^http://fav\\.me/.+$",
|
||||
"^http://sta\\.sh/.+$",
|
||||
"^http://(?:[-\\w]+\\.)?deviantart\\.com/[^#?/]+#/d.+$"
|
||||
],
|
||||
"http://blip.tv/oembed/": [
|
||||
"^http://[-\\w]+\\.blip\\.tv/.+$"
|
||||
],
|
||||
"http://www.dailymotion.com/api/oembed/": [
|
||||
"^http://[-\\w]+\\.dailymotion\\.com/.+$"
|
||||
],
|
||||
"http://www.flickr.com/services/oembed/": [
|
||||
"^http://[-\\w]+\\.flickr\\.com/photos/.+$",
|
||||
"^http://flic\\.kr\\.com/.+$"
|
||||
],
|
||||
"http://www.hulu.com/api/oembed.{format}": [
|
||||
"^http://www\\.hulu\\.com/watch/.+$"
|
||||
],
|
||||
"http://www.nfb.ca/remote/services/oembed/": [
|
||||
"^http://(?:[-\\w]+\\.)?nfb\\.ca/film/.+$"
|
||||
],
|
||||
"http://qik.com/api/oembed.{format}": [
|
||||
"^http://qik\\.com/.+$",
|
||||
"^http://qik\\.ly/.+$"
|
||||
],
|
||||
"http://revision3.com/api/oembed/": [
|
||||
"^http://[-\\w]+\\.revision3\\.com/.+$"
|
||||
],
|
||||
"http://www.scribd.com/services/oembed": [
|
||||
"^http://[-\\w]+\\.scribd\\.com/.+$"
|
||||
],
|
||||
"http://www.viddler.com/oembed/": [
|
||||
"^http://[-\\w]+\\.viddler\\.com/v/.+$",
|
||||
"^http://[-\\w]+\\.viddler\\.com/explore/.+$"
|
||||
],
|
||||
"http://www.vimeo.com/api/oembed.{format}": [
|
||||
"^http(?:s)?://(?:www\\.)?vimeo\\.com/.+$",
|
||||
"^http(?:s)?://player\\.vimeo\\.com/.+$"
|
||||
],
|
||||
"http://dotsub.com/services/oembed": [
|
||||
"^http://dotsub\\.com/view/.+$"
|
||||
],
|
||||
"http://www.yfrog.com/api/oembed": [
|
||||
"^http(?:s)?://(?:www\\.)?yfrog\\.com/.+$",
|
||||
"^http(?:s)?://(?:www\\.)?yfrog\\.us/.+$"
|
||||
],
|
||||
"http://clikthrough.com/services/oembed": [
|
||||
"^http(?:s)?://(?:[-\\w]+\\.)?clikthrough\\.com/.+$"
|
||||
],
|
||||
"http://www.kinomap.com/oembed": [
|
||||
"^http://[-\\w]+\\.kinomap\\.com/.+$"
|
||||
],
|
||||
"https://photobucket.com/oembed": [
|
||||
"^http://(?:[-\\w]+\\.)?photobucket\\.com/albums/.+$",
|
||||
"^http://(?:[-\\w]+\\.)?photobucket\\.com/groups/.+$"
|
||||
],
|
||||
"http://api.instagram.com/oembed": [
|
||||
"^http://instagr\\.am/p/.+$",
|
||||
"^http://instagram\\.com/p/.+$"
|
||||
],
|
||||
"https://www.slideshare.net/api/oembed/2": [
|
||||
"^http://www\\.slideshare\\.net/.+$"
|
||||
],
|
||||
"http://tv.majorleaguegaming.com/oembed": [
|
||||
"^http://mlg\\.tv/.+$",
|
||||
"^http://tv\\.majorleaguegaming\\.com/.+$"
|
||||
],
|
||||
"http://my.opera.com/service/oembed": [
|
||||
"^http://my\\.opera\\.com/.+$"
|
||||
],
|
||||
"http://skitch.com/oembed": [
|
||||
"^http(?:s)?://(?:www\\.)?skitch\\.com/.+$",
|
||||
"^http://skit\\.ch/.+$"
|
||||
],
|
||||
"https://api.twitter.com/1/statuses/oembed.{format}": [
|
||||
"^http(?:s)?://twitter\\.com/(?:#!)?[^#?/]+/status/.+$"
|
||||
],
|
||||
"https://soundcloud.com/oembed": [
|
||||
"^https://soundcloud\\.com/[^#?/]+/.+$"
|
||||
],
|
||||
"http://www.collegehumor.com/oembed.{format}": [
|
||||
"^http://(?:www\\.)?collegehumor\\.com/video/.+$",
|
||||
"^http://(?:www\\.)?collegehumor\\.com/video:.+$"
|
||||
],
|
||||
"http://www.polleverywhere.com/services/oembed/": [
|
||||
"^http://www\\.polleverywhere\\.com/polls/.+$",
|
||||
"^http://www\\.polleverywhere\\.com/multiple_choice_polls/.+$",
|
||||
"^http://www\\.polleverywhere\\.com/free_text_polls/.+$"
|
||||
],
|
||||
"http://www.ifixit.com/Embed": [
|
||||
"^http://www\\.ifixit\\.com/[^#?/]+/[^#?/]+/.+$"
|
||||
],
|
||||
"http://api.smugmug.com/services/oembed/": [
|
||||
"^http(?:s)?://(?:www\\.)?smugmug\\.com/[^#?/]+/.+$"
|
||||
],
|
||||
"https://github.com/api/oembed": [
|
||||
"^http(?:s)?://gist\\.github\\.com/.+$"
|
||||
],
|
||||
"http://animoto.com/services/oembed": [
|
||||
"^http://animoto\\.com/play/.+$"
|
||||
],
|
||||
"http://www.rdio.com/api/oembed": [
|
||||
"^http://(?:wwww\\.)?rdio\\.com/people/[^#?/]+/playlists/.+$",
|
||||
"^http://[-\\w]+\\.rdio\\.com/artist/[^#?/]+/album/.+$"
|
||||
],
|
||||
"http://api.5min.com/oembed.{format}": [
|
||||
"^http://www\\.5min\\.com/video/.+$"
|
||||
],
|
||||
"http://500px.com/photo/{1}/oembed.{format}": [
|
||||
"^http://500px\\.com/photo/([^#?/]+)(?:.+)?$"
|
||||
],
|
||||
"http://api.dipdive.com/oembed.{format}": [
|
||||
"^http://[-\\w]+\\.dipdive\\.com/media/.+$"
|
||||
],
|
||||
"http://video.yandex.ru/oembed.{format}": [
|
||||
"^http://video\\.yandex\\.ru/users/[^#?/]+/view/.+$"
|
||||
],
|
||||
"http://www.mixcloud.com/oembed/": [
|
||||
"^http://www\\.mixcloud\\.com/oembed/[^#?/]+/.+$"
|
||||
],
|
||||
"http://www.kickstarter.com/services/oembed": [
|
||||
"^http(?:s)://[-\\w]+\\.kickstarter\\.com/projects/.+$"
|
||||
],
|
||||
"http://coub.com/api/oembed.{format}": [
|
||||
"^http(?:s)?://coub\\.com/view/.+$",
|
||||
"^http(?:s)?://coub\\.com/embed/.+$"
|
||||
],
|
||||
"http://www.screenr.com/api/oembed.{format}": [
|
||||
"^http://www\\.screenr\\.com/.+$"
|
||||
],
|
||||
"http://www.funnyordie.com/oembed.{format}": [
|
||||
"^http://www\\.funnyordie\\.com/videos/.+$"
|
||||
],
|
||||
"http://fast.wistia.com/oembed.{format}": [
|
||||
"^http://[-\\w]+\\.wista\\.com/medias/.+$"
|
||||
],
|
||||
"http://www.ustream.tv/oembed": [
|
||||
"^http(?:s)?://(?:www\\.)?ustream\\.tv/.+$",
|
||||
"^http(?:s)?://(?:www\\.)?ustream\\.com/.+$",
|
||||
"^http://ustre\\.am/.+$"
|
||||
],
|
||||
"http://wordpress.tv/oembed/": [
|
||||
"^http://wordpress\\.tv/.+$"
|
||||
],
|
||||
"http://polldaddy.com/oembed/": [
|
||||
"^http(?:s)?://(?:[-\\w]+\\.)?polldaddy\\.com/.+$"
|
||||
],
|
||||
"http://api.bambuser.com/oembed.{format}": [
|
||||
"^http://bambuser\\.com/channel/[^#?/]+/broadcast/.+$",
|
||||
"^http://bambuser\\.com/channel/.+$",
|
||||
"^http://bambuser\\.com/v/.+$"
|
||||
],
|
||||
"http://www.ted.com/talks/oembed.{format}": [
|
||||
"^http(?:s)?://(?:www\\.)?ted\\.com/talks/.+$",
|
||||
"^http(?:s)?://(?:www\\.)?ted\\.com/talks/lang/[^#?/]+/.+$",
|
||||
"^http(?:s)?://(?:www\\.)?ted\\.com/index\\.php/talks/.+$",
|
||||
"^http(?:s)?://(?:www\\.)?ted\\.com/index\\.php/talks/lang/[^#?/]+/.+$"
|
||||
],
|
||||
"http://chirb.it/oembed.{format}": [
|
||||
"^http://chirb\\.it/.+$"
|
||||
],
|
||||
"https://www.circuitlab.com/circuit/oembed/": [
|
||||
"^http(?:s)?://(?:www\\.)?circuitlab\\.com/circuit/.+$"
|
||||
],
|
||||
"http://api.geograph.org.uk/api/oembed": [
|
||||
"^http://(?:[-\\w]+\\.)?geograph\\.org\\.uk/.+$",
|
||||
"^http://(?:[-\\w]+\\.)?geograph\\.co\\.uk/.+$",
|
||||
"^http://(?:[-\\w]+\\.)?geograph\\.ie/.+$"
|
||||
],
|
||||
"http://geo.hlipp.de/restapi.php/api/oembed": [
|
||||
"^http://geo-en\\.hlipp\\.de/.+$",
|
||||
"^http://geo\\.hlipp\\.de/.+$",
|
||||
"^http://germany\\.geograph\\.org/.+$"
|
||||
],
|
||||
"http://www.geograph.org.gg/api/oembed": [
|
||||
"^http://(?:[-\\w]+\\.)?geograph\\.org\\.gg/.+$",
|
||||
"^http://(?:[-\\w]+\\.)?geograph\\.org\\.je/.+$",
|
||||
"^http://channel-islands\\.geograph\\.org/.+$",
|
||||
"^http://channel-islands\\.geographs\\.org/.+$",
|
||||
"^http://(?:[-\\w]+\\.)?channel\\.geographs\\.org/.+$"
|
||||
],
|
||||
"http://vzaar.com/api/videos/{1}.{format}": [
|
||||
"^http://(?:www\\.)?vzaar\\.com/videos/([^#?/]+)(?:.+)?$",
|
||||
"^http://www\\.vzaar\\.tv/([^#?/]+)(?:.+)?$",
|
||||
"^http://vzaar\\.tv/([^#?/]+)(?:.+)?$",
|
||||
"^http://vzaar\\.me/([^#?/]+)(?:.+)?$",
|
||||
"^http://[-\\w]+\\.vzaar\\.me/([^#?/]+)(?:.+)?$"
|
||||
],
|
||||
"http://api.minoto-video.com/services/oembed.{format}": [
|
||||
"^http://api\\.minoto-video\\.com/publishers/[^#?/]+/videos/.+$",
|
||||
"^http://dashboard\\.minoto-video\\.com/main/video/details/.+$",
|
||||
"^http://embed\\.minoto-video\\.com/.+$"
|
||||
],
|
||||
"http://www.videojug.com/oembed.{format}": [
|
||||
"^http(?:s)?://(?:[-\\w]+\\.)?videojug\\.com/film/.+$",
|
||||
"^http(?:s)?://(?:[-\\w]+\\.)?videojug\\.com/payer/.+$",
|
||||
"^http(?:s)?://(?:[-\\w]+\\.)?videojug\\.com/interview/.+$"
|
||||
],
|
||||
"http://videos.sapo.pt/oembed": [
|
||||
"^http(?:s)?://videos\\.sapo\\.pt/.+$"
|
||||
],
|
||||
"http://vhx.tv/services/oembed.{format}": [
|
||||
"^http(?:s)?://(?:www\\.)?vhx\\.tv/.+$"
|
||||
],
|
||||
"http://api.justin.tv/api/embed/from_url.{format}": [
|
||||
"^http(?:s)?://(?:www\\.)?justin\\.tv/.+$"
|
||||
],
|
||||
"http://official.fm/services/oembed.{format}": [
|
||||
"^http(?:s)?://official\\.fm/.+$"
|
||||
],
|
||||
"http://huffduffer.com/oembed": [
|
||||
"^http(?:s)?://(?:www\\.)?huffduffer\\.com/[^#?/]+/.+$"
|
||||
],
|
||||
"https://embed.spotify.com/oembed/": [
|
||||
"^http(?:s)?://open\\.spotify\\.com/.+$",
|
||||
"^http(?:s)?://spoti\\.fi/.+$"
|
||||
],
|
||||
"http://shoudio.com/api/oembed": [
|
||||
"^http://shoudio\\.com/.+$",
|
||||
"^http://shoud\\.io/.+$"
|
||||
],
|
||||
"http://api.mobypicture.com/oEmbed": [
|
||||
"^http(?:s)?://(?:www\\.)?mobypicture\\.com/user/[^#?/]+/view/.+$",
|
||||
"^http(?:s)?://(?:www\\.)?moby\\.to/.+$"
|
||||
],
|
||||
"http://www.23hq.com/23/oembed": [
|
||||
"^http(?:s)?://(?:www\\.)?23hq\\.com/[^#?/]+/photo/.+$"
|
||||
],
|
||||
"http://gmep.org/oembed.{format}": [
|
||||
"^http(?:s)?://(?:www\\.)?gmep\\.org/.+$",
|
||||
"^http(?:s)?://gmep\\.imeducate\\.com/.+$"
|
||||
],
|
||||
"http://oembed.urtak.com/1/oembed": [
|
||||
"^http(?:s)?://(?:[-\\w]+\\.)?urtak\\.com/.+$"
|
||||
],
|
||||
"http://cacoo.com/oembed.{format}": [
|
||||
"^http(?:s)?://cacoo\\.com/.+$"
|
||||
],
|
||||
"http://api.dailymile.com/oembed": [
|
||||
"^http(?:s)?://(?:www\\.)?dailymile\\.com/people/[^#?/]+/entries/.+$"
|
||||
],
|
||||
"http://www.dipity.com/oembed/timeline/": [
|
||||
"^http(?:s)?://(?:www\\.)?dipity\\.com/timeline/.+$",
|
||||
"^http(?:s)?://(?:www\\.)?dipity\\.com/voaweb/.+$"
|
||||
],
|
||||
"https://sketchfab.com/oembed": [
|
||||
"^http(?:s)?://sketchfab\\.com/show/.+$"
|
||||
],
|
||||
"https://api.meetup.com/oembed": [
|
||||
"^http(?:s)?://(?:www\\.)?meetup\\.com/.+$",
|
||||
"^http(?:s)?://(?:www\\.)?meetup\\.ps/.+$"
|
||||
],
|
||||
"https://roomshare.jp/oembed.{format}": [
|
||||
"^http(?:s)?://(?:www\\.)?roomshare\\.jp/(?:en/)?post/.+$"
|
||||
],
|
||||
"http://crowdranking.com/api/oembed.{format}": [
|
||||
"^http(?:s)?://crowdranking\\.com/crowdrankings/.+$",
|
||||
"^http(?:s)?://crowdranking\\.com/rankings/.+$",
|
||||
"^http(?:s)?://crowdranking\\.com/topics/.+$",
|
||||
"^http(?:s)?://crowdranking\\.com/widgets/.+$",
|
||||
"^http(?:s)?://crowdranking\\.com/r/.+$"
|
||||
],
|
||||
"http://openapi.etsy.com/svc/oembed/": [
|
||||
"^http(?:s)?://(?:www\\.)?etsy\\.com/listing/.+$"
|
||||
],
|
||||
"https://audioboo.fm/publishing/oembed.{format}": [
|
||||
"^http(?:s)?://audioboo\\.fm/boos/.+$"
|
||||
],
|
||||
"http://demo.clikthrough.com/services/oembed/": [
|
||||
"^http(?:s)?://demo\\.clikthrough\\.com/theater/video/.+$"
|
||||
],
|
||||
"http://www.ifttt.com/oembed/": [
|
||||
"^http(?:s)?://ifttt\\.com/recipes/.+$"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
import os, re
|
||||
import urllib2, urllib
|
||||
from datetime import datetime
|
||||
import json
|
||||
|
||||
class NotImplementedOembedException(Exception):
|
||||
pass
|
||||
|
||||
ENDPOINTS = {}
|
||||
|
||||
def get_embed_oembed(url, max_width=None):
|
||||
provider = None
|
||||
for endpoint in ENDPOINTS.keys():
|
||||
for pattern in ENDPOINTS[endpoint]:
|
||||
if re.match(pattern, url):
|
||||
provider = endpoint
|
||||
break
|
||||
if not provider:
|
||||
raise NotImplementedOembedException
|
||||
params = {'url': url, 'format': 'json', }
|
||||
if max_width:
|
||||
params['maxwidth'] = max_width
|
||||
req = provider+'?' +urllib.urlencode(params)
|
||||
request = urllib2.Request(req)
|
||||
opener = urllib2.build_opener()
|
||||
# Some provicers were not working without a user agent
|
||||
request.add_header('User-Agent','Mozilla/5.0')
|
||||
return json.loads(opener.open(request).read())
|
||||
|
||||
|
||||
# Uses the public domain collection of oembed endpoints by Mathias Panzenbpeck (panzi)
|
||||
# at https://github.com/panzi/oembedendpoints/blob/master/endpoints-regexp.json
|
||||
|
||||
def load_oembed_endpoints():
|
||||
module_dir = os.path.dirname(__file__)
|
||||
endpoints_path = os.path.join(module_dir, 'endpoints.json')
|
||||
with open( endpoints_path) as f:
|
||||
endpoints = json.loads(f.read())
|
||||
|
||||
for endpoint in endpoints.keys():
|
||||
endpoint_key = endpoint.replace('{format}', 'json')
|
||||
|
||||
ENDPOINTS[endpoint_key]=[]
|
||||
for pattern in endpoints[endpoint]:
|
||||
ENDPOINTS[endpoint_key].append(re.compile(pattern))
|
||||
|
||||
|
||||
|
||||
load_oembed_endpoints()
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
import unittest
|
||||
import oembed
|
||||
|
||||
# Test that a bunch of oembed examples is working
|
||||
# If any of these is removed or changed then the unit test will fail
|
||||
# This is a unittest TestCase (and not a django.test one) since django
|
||||
# database is not actually needed for these tests
|
||||
|
||||
TEST_DATA = [
|
||||
{
|
||||
'url':'http://www.youtube.com/watch?v=S3xAeTmsJfg',
|
||||
'title':'Animation: Ferret dance (A series of tubes)'
|
||||
},
|
||||
{
|
||||
'url':'http://vimeo.com/86036070',
|
||||
'title':'Wagtail: A new Django CMS'
|
||||
},
|
||||
{
|
||||
'url':'https://speakerdeck.com/harmstyler/an-introduction-to-django',
|
||||
'title':'An Introduction to Django'
|
||||
},
|
||||
{
|
||||
'url':'https://ifttt.com/recipes/144705-new-twitter-followers-in-a-google-spreadsheet',
|
||||
'title':'New Twitter followers in a Google spreadsheet'
|
||||
},
|
||||
{
|
||||
'url':'http://www.hulu.com/watch/20807/late-night-with-conan-obrien-wed-may-21-2008',
|
||||
'title':'Wed, May 21, 2008 (Late Night With Conan O\'Brien)'
|
||||
},
|
||||
{
|
||||
'url':'http://www.flickr.com/photos/dfluke/5995957175/',
|
||||
'title':'Django pony!?'
|
||||
},
|
||||
{
|
||||
'url':'http://www.slideshare.net/simon/the-django-web-application-framework',
|
||||
'title':'The Django Web Application Framework'
|
||||
},
|
||||
{
|
||||
'url':'http://www.rdio.com/artist/The_Black_Keys/album/Brothers/',
|
||||
'title':'Brothers'
|
||||
},
|
||||
{
|
||||
'url':'http://instagram.com/p/kFKCcEKmBq/',
|
||||
'title':'Family holidays in #Greece!'
|
||||
},
|
||||
{
|
||||
'url':'https://www.kickstarter.com/projects/noujaimfilms/the-square-a-film-about-the-egyptian-revolution',
|
||||
'title':'Sundance Award Winning Film on the Egyptian Revolution'
|
||||
},
|
||||
{
|
||||
'url':'http://www.dailymotion.com/video/xoxulz_babysitter_animals',
|
||||
'title':'Babysitter!'
|
||||
}
|
||||
]
|
||||
|
||||
class TestEmbeds(unittest.TestCase):
|
||||
def test_get_embed_oembed(self):
|
||||
for td in TEST_DATA:
|
||||
embed = oembed.get_embed_oembed_low(td['url'])
|
||||
self.assertEqual(embed['title'], td['title'] )
|
||||
self.assertIsNotNone(embed['type'] )
|
||||
self.assertIsNotNone(embed['width'] )
|
||||
self.assertIsNotNone(embed['height'] )
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -2,21 +2,24 @@ from __future__ import division # Use true division
|
|||
|
||||
from django.utils.html import escape
|
||||
|
||||
from .embeds import get_embed
|
||||
from .embeds.embed import get_embed
|
||||
|
||||
|
||||
def embed_to_frontend_html(url):
|
||||
embed = get_embed(url)
|
||||
if embed is not None:
|
||||
# Work out ratio
|
||||
if embed.width and embed.height:
|
||||
ratio = str(embed.height / embed.width * 100) + "%"
|
||||
else:
|
||||
ratio = "0"
|
||||
try:
|
||||
embed = get_embed(url)
|
||||
if embed is not None:
|
||||
# Work out ratio
|
||||
if embed.width and embed.height:
|
||||
ratio = str(embed.height / embed.width * 100) + "%"
|
||||
else:
|
||||
ratio = "0"
|
||||
|
||||
# Build html
|
||||
return '<div style="padding-bottom: %s;" class="responsive-object">%s</div>' % (ratio, embed.html)
|
||||
else:
|
||||
# Build html
|
||||
return '<div style="padding-bottom: %s;" class="responsive-object">%s</div>' % (ratio, embed.html)
|
||||
else:
|
||||
return ''
|
||||
except:
|
||||
return ''
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from django import template
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
from wagtail.wagtailembeds.embeds import get_embed
|
||||
from wagtail.wagtailembeds.embed.embeds import get_embed
|
||||
|
||||
|
||||
register = template.Library()
|
||||
|
@ -10,9 +10,12 @@ register = template.Library()
|
|||
@register.filter
|
||||
def embed(url, max_width=None):
|
||||
embed = get_embed(url, max_width=max_width)
|
||||
if embed is not None:
|
||||
return mark_safe(embed.html)
|
||||
else:
|
||||
try:
|
||||
if embed is not None:
|
||||
return mark_safe(embed.html)
|
||||
else:
|
||||
return ''
|
||||
except:
|
||||
return ''
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from django.test import TestCase
|
||||
from django.test import TestCasez
|
||||
|
||||
from .embeds import get_embed
|
||||
|
||||
|
|
|
@ -5,6 +5,10 @@ from wagtail.wagtailadmin.modal_workflow import render_modal_workflow
|
|||
from wagtail.wagtailembeds.forms import EmbedForm
|
||||
from wagtail.wagtailembeds.format import embed_to_editor_html
|
||||
|
||||
from wagtail.wagtailembeds.embeds.oembed_api import NotImplementedOembedException
|
||||
from wagtail.wagtailembeds.embeds.embed import EmbedlyException, AccessDeniedEmbedlyException, NotFoundEmbedlyException
|
||||
|
||||
|
||||
|
||||
def chooser(request):
|
||||
form = EmbedForm()
|
||||
|
@ -19,18 +23,27 @@ def chooser_upload(request):
|
|||
form = EmbedForm(request.POST, request.FILES)
|
||||
|
||||
if form.is_valid():
|
||||
embed_html = embed_to_editor_html(form.cleaned_data['url'])
|
||||
if embed_html != "":
|
||||
try:
|
||||
embed_html = embed_to_editor_html(form.cleaned_data['url'])
|
||||
return render_modal_workflow(
|
||||
request, None, 'wagtailembeds/chooser/embed_chosen.js',
|
||||
{'embed_html': embed_html}
|
||||
)
|
||||
else:
|
||||
except Exception as e :
|
||||
#print e
|
||||
#import traceback
|
||||
#traceback.print_exc()
|
||||
errors = form._errors.setdefault('url', ErrorList())
|
||||
if not hasattr(settings, 'EMBEDLY_KEY'):
|
||||
errors.append('Please set EMBEDLY_KEY in your settings')
|
||||
if type(e) == NotImplementedOembedException:
|
||||
errors.append("This URL is not supported by an oembed provider. You may try embedding it using Embedly by setting a propery EMBEDLY_KEY in your settings.")
|
||||
elif type(e) == AccessDeniedEmbedlyException:
|
||||
errors.append("There seems to be a problem with your embedly API key. Please check your settings.")
|
||||
elif type(e) == NotFoundEmbedlyException:
|
||||
errors.append("The URL you are trying to embed cannot be found.")
|
||||
elif type(e) == EmbedlyException:
|
||||
errors.append("There seems to be an error with Embedly while trying to embed this URL. Please try again later.")
|
||||
else:
|
||||
errors.append('This URL is not recognised')
|
||||
errors.append(str(e) )
|
||||
return render_modal_workflow(request, 'wagtailembeds/chooser/chooser.html', 'wagtailembeds/chooser/chooser.js', {
|
||||
'form': form,
|
||||
})
|
||||
|
|
Ładowanie…
Reference in New Issue