Merge branch 'master' of github.com:torchbox/wagtail

pull/37/head
Matt Westcott 2014-02-13 12:44:57 +00:00
commit 069ff69335
15 zmienionych plików z 692 dodań i 30 usunięć

Wyświetl plik

@ -1,8 +1,21 @@
Wagtail CMS
===========
Wagtail is a Django content management system focused on flexibility and user experience. Find out more at `wagtail.io <http://wagtail.io/>`_
and `torchbox.github.io/wagtail <http://torchbox.github.io/wagtail/>`_.
Wagtail is a Django content management system built originally for the `Royal College of Art <http://www.rca.ac.uk/>`_ and focused on flexibility and user experience. Its features include:
* A fast, attractive editor interface
* Complete control over design with standard Django templates
* Configure content types through standard Django models
* Tightly integrated search (with an `Elasticsearch <http://www.elasticsearch.org/>`_ backend for production)
* Strong document and image management
* Wide support for embedded content
* Simple, configurable permissions
* Support for tree-based content organisation
* Optional preview->submit->approve workflow
* Fast out of the box. `Varnish <https://www.varnish-cache.org/>`_-friendly if you need it
* Tests! But not enough; we're working hard to improve this
Find out more at `wagtail.io <http://wagtail.io/>`_.
Getting started
~~~~~~~~~~~~~~~
@ -10,4 +23,4 @@ To get you up and running quickly, we've provided a demonstration site with all
Contributing
~~~~~~~~~~~~
If you're a Python or Django developer, fork the repo and get stuck in! Send us a useful pull request and we'll post you a `t-shirt <https://twitter.com/WagtailCMS/status/432166799464210432/photo/1>`_.
If you're a Python or Django developer, fork the repo and get stuck in! Send us a useful pull request and we'll post you a `t-shirt <https://twitter.com/WagtailCMS/status/432166799464210432/photo/1>`_. Our immediate priorities are better docs, more tests, internationalisation and localisation.

Wyświetl plik

@ -43,7 +43,6 @@ setup(
"South>=0.8.4",
"django-compressor>=1.3",
"django-modelcluster>=0.1",
"Embedly>=0.5.0",
"django-taggit>=0.11.2",
"Pillow>=2.3.0",
"beautifulsoup4>=4.3.2",

Wyświetl plik

@ -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'])

Wyświetl plik

@ -1,2 +1,2 @@
from .models import Embed
from .embeds import get_embed
from .embeds.embed import get_embed

Wyświetl plik

@ -1,12 +1,18 @@
from datetime import datetime
from embedly import Embedly
from django.conf import settings
from .models import Embed
import os
module_dir = os.path.dirname(__file__) # get current directory
file_path = os.path.join(module_dir, 'endpoints.json')
print file_path
print open(file_path).read()
def get_embed(url, max_width=None):
def get_embed_embedly(url, max_width=None):
# Check database
try:
return Embed.objects.get(url=url, max_width=max_width)
@ -52,3 +58,18 @@ def get_embed(url, max_width=None):
# Return new embed
return row
def get_embed_oembed(url, max_width=None):
pass
get_embed = get_embed_oembed
try:
from embedly import Embedly
if hasattr(settings,'EMBEDLY_KEY'):
get_embed = get_embed_embedly
except:
pass
print get_embed

Wyświetl plik

@ -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

Wyświetl plik

@ -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/.+$"
]
}

Wyświetl plik

@ -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()

Wyświetl plik

@ -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()

Wyświetl plik

@ -0,0 +1,114 @@
[
{
"url": "http://*.blip.tv/*",
"url_re": "blip\\.tv/.+",
"example_url": "http://pycon.blip.tv/file/2058801/",
"endpoint_url": "http://blip.tv/oembed/",
"title": "blip.tv"
},
{
"url": "http://*.dailymotion.com/*",
"url_re": "dailymotion\\.com/.+",
"example_url": "http://www.dailymotion.com/video/x5ioet_phoenix-mars-lander_tech",
"endpoint_url": "http://www.dailymotion.com/api/oembed/",
"title": "Dailymotion"
},
{
"url": "http://*.flickr.com/photos/*",
"url_re": "flickr\\.com/photos/[-.\\w@]+/\\d+/?",
"example_url": "http://www.flickr.com/photos/fuffer2005/2435339994/",
"endpoint_url": "http://www.flickr.com/services/oembed/",
"title": "Flickr Photos"
},
{
"url": "http://www.hulu.com/watch/*",
"url_re": "hulu\\.com/watch/.*",
"example_url": "http://www.hulu.com/watch/20807/late-night-with-conan",
"endpoint_url": "http://www.hulu.com/api/oembed.json",
"title": "Hulu"
},
{
"url": "http://*.nfb.ca/film/*",
"url_re": "nfb\\.ca/film/[-\\w]+/?",
"example_url": "http://www.nfb.ca/film/blackfly/",
"endpoint_url": "http://www.nfb.ca/remote/services/oembed/",
"title": "National Film Board of Canada"
},
{
"url": "http://qik.com/*",
"url_re": "qik\\.com/\\w+",
"example_url": "http://qik.com/video/86776",
"endpoint_url": "http://qik.com/api/oembed.json",
"title": "Qik Video"
},
{
"url": "http://*.revision3.com/*",
"url_re": "revision3\\.com/.+",
"example_url": "http://revision3.com/diggnation/2008-04-17xsanned/",
"endpoint_url": "http://revision3.com/api/oembed/",
"title": "Revision3"
},
{
"url": "http://*.scribd.com/*",
"url_re": "scribd\\.com/.+",
"example_url": "http://www.scribd.com/doc/17896323/Indian-Automobile-industryPEST",
"endpoint_url": "http://www.scribd.com/services/oembed",
"title": "Scribd"
},
{
"url": "http://*.viddler.com/explore/*",
"url_re": "viddler\\.com/explore/.*/videos/\\w+/?",
"example_url": "http://www.viddler.com/explore/engadget/videos/14/",
"endpoint_url": "http://lab.viddler.com/services/oembed/",
"title": "Viddler Video"
},
{
"url": "http://www.vimeo.com/* and http://www.vimeo.com/groups/*/videos/*",
"url_re": "vimeo\\.com/.*",
"example_url": "http://www.vimeo.com/1211060",
"endpoint_url": "http://www.vimeo.com/api/oembed.json",
"title": "Vimeo"
},
{
"url": "http://*.youtube.com/watch*",
"url_re": "youtube\\.com/watch.+v=[\\w-]+&?",
"example_url": "http://www.youtube.com/watch?v=vk1HvP7NO5w",
"endpoint_url": "http://www.youtube.com/oembed",
"title": "YouTube"
},
{
"url": "http://dotsub.com/view/*",
"url_re": "dotsub\\.com/view/[-\\da-zA-Z]+$",
"example_url": "http://dotsub.com/view/10e3cb5e-96c7-4cfb-bcea-8ab11e04e090",
"endpoint_url": "http://dotsub.com/services/oembed",
"title": "dotSUB.com"
},
{
"url": "http://yfrog.(com|ru|com.tr|it|fr|co.il|co.uk|com.pl|pl|eu|us)/*",
"url_re": "yfrog\\.(com|ru|com\\.tr|it|fr|co\\.il|co\\.uk|com\\.pl|pl|eu|us)/[a-zA-Z0-9]+$",
"example_url": "http://yfrog.com/0wgvcpj",
"endpoint_url": "http://www.yfrog.com/api/oembed",
"title": "YFrog"
},
{
"url": "http://*.clikthrough.com/theater/video/*",
"url_re": "clikthrough\\.com/theater/video/\\d+$",
"example_url": "http://www.clikthrough.com/theater/video/55",
"endpoint_url": "http://clikthrough.com/services/oembed",
"title": "Clikthrough"
},
{
"url": "http://*.kinomap.com/*",
"url_re": "kinomap\\.com/.+",
"example_url": "http://www.kinomap.com/kms-vzkpc7",
"endpoint_url": "http://www.kinomap.com/oembed",
"title": "Kinomap"
},
{
"url": "http://*.photobucket.com/albums/*|http://*.photobucket.com/groups/*",
"url_re": "photobucket\\.com/(albums|groups)/.+$",
"example_url": "http://img.photobucket.com/albums/v211/JAV123/Michael%20Holland%20Candle%20Burning/_MG_5661.jpg",
"endpoint_url": "http://photobucket.com/oembed",
"title": "Photobucket"
}
]

Wyświetl plik

@ -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 ''

Wyświetl plik

@ -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 ''

Wyświetl plik

@ -1,4 +1,4 @@
from django.test import TestCase
from django.test import TestCasez
from .embeds import get_embed

Wyświetl plik

@ -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,
})