more flexible oEmbed handling

This commit is contained in:
Evan Prodromou 2011-04-06 17:57:33 -04:00
parent 17c8df76f1
commit 4b5f76d688
3 changed files with 73 additions and 24 deletions

16
README
View File

@ -1393,12 +1393,22 @@ desclimit: maximum number of characters to allow in group descriptions.
null (default) means to use the site-wide text limits. 0 null (default) means to use the site-wide text limits. 0
means no limit. means no limit.
oohembed oembed
-------- --------
oEmbed endpoint for multimedia attachments (links in posts). oEmbed endpoint for multimedia attachments (links in posts). Will also
work as 'oohembed' for backwards compatibility.
endpoint: oohembed endpoint using http://oohembed.com/ software. endpoint: oohembed endpoint using http://oohembed.com/ software. Defaults to
'http://oohembed.com/oohembed/'.
order: Array of methods to check for OEmbed data. Methods include 'built-in'
(use a built-in function to simulate oEmbed for some sites),
'well-known' (use well-known public oEmbed endpoints),
'discovery' (discover using <link> headers in HTML), 'service' (use
a third-party service, like oohembed or embed.ly. Default is
array('built-in', 'well-known', 'service', 'discovery'). Note that very
few sites implement oEmbed; 'discovery' is going to fail 99% of the
time.
search search
------ ------

View File

@ -269,7 +269,10 @@ $default =
'group' => 'group' =>
array('maxaliases' => 3, array('maxaliases' => 3,
'desclimit' => null), 'desclimit' => null),
'oohembed' => array('endpoint' => 'http://oohembed.com/oohembed/'), 'oembed' =>
array('endpoint' => 'http://oohembed.com/oohembed/',
'order' => array('built-in', 'well-known', 'service', 'discovery'),
),
'search' => 'search' =>
array('type' => 'fulltext'), array('type' => 'fulltext'),
'sessions' => 'sessions' =>

View File

@ -43,6 +43,13 @@ class oEmbedHelper
protected static $apiMap = array( protected static $apiMap = array(
'flickr.com' => 'http://www.flickr.com/services/oembed/', 'flickr.com' => 'http://www.flickr.com/services/oembed/',
'yfrog.com' => 'http://www.yfrog.com/api/oembed', 'yfrog.com' => 'http://www.yfrog.com/api/oembed',
'youtube.com' => 'http://www.youtube.com/oembed',
'viddler.com' => 'http://lab.viddler.com/services/oembed/',
'qik.com' => 'http://qik.com/api/oembed.json',
'revision3.com' => 'http://revision3.com/api/oembed/',
'hulu.com' => 'http://www.hulu.com/api/oembed.json',
'vimeo.com' => 'http://www.vimeo.com/api/oembed.json',
'my.opera.com' => 'http://my.opera.com/service/oembed',
); );
protected static $functionMap = array( protected static $functionMap = array(
'twitpic.com' => 'oEmbedHelper::twitPic', 'twitpic.com' => 'oEmbedHelper::twitPic',
@ -74,30 +81,59 @@ class oEmbedHelper
$host = substr($host, 4); $host = substr($host, 4);
} }
// Blacklist: systems with no oEmbed API of their own, which are common_log(LOG_INFO, 'Checking for oEmbed data for ' . $url);
// either missing from or broken on oohembed.com's proxy.
// we know how to look data up in another way...
if (array_key_exists($host, self::$functionMap)) {
$func = self::$functionMap[$host];
return call_user_func($func, $url, $params);
}
// Whitelist: known API endpoints for sites that don't provide discovery... // You can fiddle with the order of discovery -- either skipping
if (array_key_exists($host, self::$apiMap)) { // some types or re-ordering them.
$api = self::$apiMap[$host];
} else { $order = common_config('oembed', 'order');
try {
$api = self::discover($url); foreach ($order as $method) {
} catch (Exception $e) {
// Discovery failed... fall back to oohembed if enabled. switch ($method) {
$oohembed = common_config('oohembed', 'endpoint'); case 'built-in':
if ($oohembed) { common_log(LOG_INFO, 'Considering built-in oEmbed methods...');
$api = $oohembed; // Blacklist: systems with no oEmbed API of their own, which are
} else { // either missing from or broken on oohembed.com's proxy.
throw $e; // we know how to look data up in another way...
if (array_key_exists($host, self::$functionMap)) {
common_log(LOG_INFO, 'We have a built-in method for ' . $host);
$func = self::$functionMap[$host];
return call_user_func($func, $url, $params);
} }
break;
case 'well-known':
common_log(LOG_INFO, 'Considering well-known oEmbed endpoints...');
// Whitelist: known API endpoints for sites that don't provide discovery...
if (array_key_exists($host, self::$apiMap)) {
$api = self::$apiMap[$host];
common_log(LOG_INFO, 'Using well-known endpoint "' . $api . '" for "' . $host . '"');
break 2;
}
break;
case 'discovery':
try {
common_log(LOG_INFO, 'Trying to discover an oEmbed endpoint using link headers.');
$api = self::discover($url);
common_log(LOG_INFO, 'Found API endpoint ' . $api . ' for URL ' . $url);
break 2;
} catch (Exception $e) {
common_log(LOG_INFO, 'Could not find an oEmbed endpoint using link headers.');
// Just ignore it!
}
break;
case 'service':
$api = common_config('oembed', 'endpoint');
common_log(LOG_INFO, 'Using service API endpoint ' . $api);
break 2;
break;
} }
} }
if (empty($api)) {
throw new ServerException(_('No oEmbed API endpoint available.'));
}
return self::getObjectFrom($api, $url, $params); return self::getObjectFrom($api, $url, $params);
} }