diff --git a/serendipity_event_oembed/ChangeLog b/serendipity_event_oembed/ChangeLog new file mode 100644 index 00000000..e6f161c3 --- /dev/null +++ b/serendipity_event_oembed/ChangeLog @@ -0,0 +1,3 @@ +Version 1.00 (brockhaus) +----------------------- +* Initial Release, have fun! :) \ No newline at end of file diff --git a/serendipity_event_oembed/CurlFetcher.php b/serendipity_event_oembed/CurlFetcher.php new file mode 100644 index 00000000..9792cf5c --- /dev/null +++ b/serendipity_event_oembed/CurlFetcher.php @@ -0,0 +1,79 @@ + array ( 'method' => 'GET', 'max_redirects' => $max_redirects, ),); + $file_content = file_get_contents($fileurl, null, stream_context_create($context)); + } + return $file_content; + } + + /** + * Handling redirections with curl if safe_mode or open_basedir is enabled. The function working transparent, no problem with header and returntransfer options. You can handle the max redirection with the optional second argument (the function is set the variable to zero if max redirection exceeded). + * Second parameter values: + * - maxredirect is null or not set: redirect maximum five time, after raise PHP warning + * - maxredirect is greather then zero: no raiser error, but parameter variable set to zero + * - maxredirect is less or equal zero: no follow redirections + * (see: http://php.net/manual/en/function.curl-setopt.php) + */ + private function curl_exec_follow(/*resource*/ $ch, /*int*/ &$maxredirect = null) { + $mr = $maxredirect === null ? 5 : intval($maxredirect); + if (ini_get('open_basedir') == '' && ini_get('safe_mode' == 'Off')) { + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $mr > 0); + curl_setopt($ch, CURLOPT_MAXREDIRS, $mr); + } else { + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false); + if ($mr > 0) { + $newurl = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); + + $rch = curl_copy_handle($ch); + curl_setopt($rch, CURLOPT_HEADER, true); + curl_setopt($rch, CURLOPT_NOBODY, true); + curl_setopt($rch, CURLOPT_FORBID_REUSE, false); + curl_setopt($rch, CURLOPT_RETURNTRANSFER, true); + do { + curl_setopt($rch, CURLOPT_URL, $newurl); + $header = curl_exec($rch); + if (curl_errno($rch)) { + $code = 0; + } else { + $code = curl_getinfo($rch, CURLINFO_HTTP_CODE); + if ($code == 301 || $code == 302) { + preg_match('/Location:(.*?)\n/', $header, $matches); + $newurl = trim(array_pop($matches)); + } else { + $code = 0; + } + } + } while ($code && --$mr); + curl_close($rch); + if (!$mr) { + if ($maxredirect === null) { + trigger_error('Too many redirects. When following redirects, libcurl hit the maximum amount.', E_USER_WARNING); + } else { + $maxredirect = 0; + } + return false; + } + curl_setopt($ch, CURLOPT_URL, $newurl); + } + } + return curl_exec($ch); + } +} \ No newline at end of file diff --git a/serendipity_event_oembed/OEmbedDatabase.php b/serendipity_event_oembed/OEmbedDatabase.php new file mode 100644 index 00000000..e994584c --- /dev/null +++ b/serendipity_event_oembed/OEmbedDatabase.php @@ -0,0 +1,99 @@ +html)) { + $oembed->html = OEmbedDatabase::cleanup_html($oembed->html); + } + $save = array(); + $save['urlmd5'] = md5($url); + $save['url'] = $url; + $save['oetype'] = $oembed->type; + $save['oeobj'] = serialize($oembed); + serendipity_db_insert( PLUGIN_OEMBED_DATABASEVNAME, $save ); + return $oembed; + } + + function load_oembed($url) { + global $serendipity; + if (empty($url)) return null; + + $urlmd5 = md5($url); + $query = "select oeobj from {$serendipity['dbPrefix']}" . PLUGIN_OEMBED_DATABASEVNAME . " where urlmd5='$urlmd5'"; + + $rows = serendipity_db_query($query); + if (!is_array($rows)) { // fresh search + return null; + } + else { + $oeobj = null; + foreach ($rows as $row) { + $oeobj = $row['oeobj']; + if (!empty($oeobj)) break; + } + if (!empty($oeobj)) { + return unserialize($oeobj); + } + + } + return null; + } + function clear_cache() { + global $serendipity; + $q = "delete from {$serendipity['dbPrefix']}" . PLUGIN_OEMBED_DATABASEVNAME; + serendipity_db_schema_import($q); + } + + function install(&$obj) { + global $serendipity; + + if (!OEmbedDatabase::table_created(PLUGIN_OEMBED_DATABASEVNAME)) { + $md5test = md5("test"); + $md5len = strlen($md5test); + $q = "create table {$serendipity['dbPrefix']}" . PLUGIN_OEMBED_DATABASEVNAME. " (" . + "urlmd5 char($md5len) not null, " . + "url varchar(3000) not null, " . + "oetype varchar(20) not null, " . + "oeobj text not null, " . + "primary key (urlmd5)" . + ")"; + + $result = serendipity_db_schema_import($q); + + if ($result !== true) { + return; + } + } + } + + + function table_created($table = PLUGIN_OEMBED_DATABASEVNAME) { + global $serendipity; + + $q = "select count(*) from {$serendipity['dbPrefix']}" . $table; + $row = serendipity_db_query($q, true, 'num'); + + if (!is_numeric($row[0])) { // if the response we got back was an SQL error.. :P + return false; + } else { + return true; + } + } + + function cleanup_html( $str ) { + $str = trim($str); + // Clear unicode stuff + $str=str_ireplace("\u003C","<",$str); + $str=str_ireplace("\u003E",">",$str); + // Clear CDATA Trash. + $str = preg_replace("@^$@", '$1', $str); + $str = preg_replace("@^$@", '$1', $str); + return $str; + } + +} \ No newline at end of file diff --git a/serendipity_event_oembed/OEmbedTemplater.php b/serendipity_event_oembed/OEmbedTemplater.php new file mode 100644 index 00000000..2e35757c --- /dev/null +++ b/serendipity_event_oembed/OEmbedTemplater.php @@ -0,0 +1,35 @@ +assign('oembedurl',$url); + $serendipity['smarty']->assign('oembed',(array)$oembed); + $tfile = serendipity_getTemplateFile($filename, 'serendipityPath'); + if (!$tfile || $filename == $tfile) { + $tfile = dirname(__FILE__) . '/' . $filename; + } + + $inclusion = $serendipity['smarty']->security_settings[@INCLUDE_ANY]; + $serendipity['smarty']->security_settings[@INCLUDE_ANY] = true; + + if (version_compare($serendipity['version'], '1.7-alpha1','>=')) { + $serendipity['smarty']->disableSecurity(); + } + else { + $serendipity['smarty']->security = false; + } + + // be smarty 3 compat including the serendipity_smarty class wrappers ->fetch and ->display methods and remove changed parameter number 4 + $content = @$serendipity['smarty']->fetch('file:'. $tfile);//, false + + $serendipity['smarty']->security_settings[@INCLUDE_ANY] = $inclusion; + + return $content; + } +} \ No newline at end of file diff --git a/serendipity_event_oembed/lang_de.inc.php b/serendipity_event_oembed/lang_de.inc.php new file mode 100755 index 00000000..3896913c --- /dev/null +++ b/serendipity_event_oembed/lang_de.inc.php @@ -0,0 +1,9 @@ + + * EN-Revision: Revision of lang_en.inc.php + */ + +@define('PLUGIN_EVENT_OEMBED_NAME', 'oEmbed Plugin'); diff --git a/serendipity_event_oembed/lang_en.inc.php b/serendipity_event_oembed/lang_en.inc.php new file mode 100755 index 00000000..4452f636 --- /dev/null +++ b/serendipity_event_oembed/lang_en.inc.php @@ -0,0 +1,26 @@ + + * EN-Revision: Revision of lang_en.inc.php + */ + +@define('PLUGIN_EVENT_OEMBED_NAME', 'oEmbed Plugin'); +@define('PLUGIN_EVENT_OEMBED_DESC', 'oEmbed is a format for allowing an embedded representation of a URL on your blog. It allows blog articles to display embedded content (such as tweets, photos or videos) when a user posts a link to that resource, without having to parse the resource directly.'); + +@define('PLUGIN_EVENT_OEMBED_MAXWIDTH', 'Max width of replacements'); +@define('PLUGIN_EVENT_OEMBED_MAXWIDTH_DESC', 'This is the max width the service should produce when providing a replacement. Not all services supports this but most.'); +@define('PLUGIN_EVENT_OEMBED_MAXHEIGHT', 'Max height of replacements'); +@define('PLUGIN_EVENT_OEMBED_MAXHEIGHT_DESC','This is the max height the service should produce when providing a replacement. Not all services supports this but most.'); + +@define('PLUGIN_EVENT_OEMBED_INFO', '

oEmbed Plugin

' . +'

'. +'This plugin expands URLs to pages of known services to a representation of that URL. It shows i.e. the video for a youtube URL or the image instead of a flickr URL.
' . +'The syntax of this plugin is [embed link] (or [e link] if you like it shorter).
'. +'If the link is not supported by the plugin at the moment, it will replace the URL by a link pointing to that URL.
'. +'

'. +'Please put this plugin at the top of your plugins list, so no other plugin can change this syntax (by adding a href i.e.)'. +'

'. +'The plugin supports representations of the following link types:%s'. +'

'); diff --git a/serendipity_event_oembed/oembed.tpl b/serendipity_event_oembed/oembed.tpl new file mode 100644 index 00000000..2d574e58 --- /dev/null +++ b/serendipity_event_oembed/oembed.tpl @@ -0,0 +1,31 @@ +{* oembed.tpl last modified 2011-12-01 *} + +{if $oembed.type=='rich'} {* =================================================== RICH *} +{if $oembed.provider_name=="Wikipedia"} +
{$oembed.html}
+{elseif $oembed.provider_name=="IMDB"} {* beautify IMDB content *} +
{$oembed.html|replace:"

":""|replace:"

":""|replace:" +{elseif $oembed.provider-name=="Soundcloud"} {* beautify SoundCloud *} +{$oembed.html|replace:"":"
"} +{else} +{$oembed.html} +{/if} +{elseif $oembed.type=='video'} {* =================================================== VIDEO *} +{$oembed.html} +{elseif $oembed.type=='image'} {* =================================================== IMAGE *} +{$oembed.title} +{elseif $oembed.type=='photo'} {* =================================================== PHOTO *} +{$oembed.title} +{elseif $oembed.type=='link'} {* =================================================== LINK *} +{if $oembed.provider_name=="Wikipedia"}
{/if} +{if $oembed.description} +{if $oembed.title}{$oembed.title}
{/if} +

{if $oembed.thumbnail_url}{/if}{$oembed.description}{if $oembed.url}
[link]{/if}

+{else} +{$oembed.author_name} +{/if} +{if $oembed.provider_name=="Wikipedia"}
{/if} +{else} {* Link type finishes *} +{if $oembed.error}{$oembed.error}{else}{$oembedurl}{/if} +{/if} + \ No newline at end of file diff --git a/serendipity_event_oembed/oembed/EmbedProvider.class.php b/serendipity_event_oembed/oembed/EmbedProvider.class.php new file mode 100644 index 00000000..5187d849 --- /dev/null +++ b/serendipity_event_oembed/oembed/EmbedProvider.class.php @@ -0,0 +1,16 @@ +url = $url; + $this->endpoint = $endpoint; + $this->maxwidth = $maxwidth; + $this->maxheight = $maxheight; + } +} diff --git a/serendipity_event_oembed/oembed/Exception404.class.php b/serendipity_event_oembed/oembed/Exception404.class.php new file mode 100644 index 00000000..4e93adf4 --- /dev/null +++ b/serendipity_event_oembed/oembed/Exception404.class.php @@ -0,0 +1,3 @@ +$value){ + $this->$key=(string)$value; + } + } +} + diff --git a/serendipity_event_oembed/oembed/OEmbedProvider.class.php b/serendipity_event_oembed/oembed/OEmbedProvider.class.php new file mode 100644 index 00000000..f0205c97 --- /dev/null +++ b/serendipity_event_oembed/oembed/OEmbedProvider.class.php @@ -0,0 +1,103 @@ +onlyJson = $onlyJson; + $this->dimensionsSupported = $dimensionsSupported; + $this->urlRegExp=preg_replace(array("/\*/","/\//","/\.\*\./"),array(".*","\/",".*"),$url); + $this->urlRegExp="/".$this->urlRegExp."/"; + if (preg_match("/\{format\}/",$endpoint)){ + $this->jsonEndpoint=preg_replace("/\{format\}/","json",$endpoint); + $this->jsonEndpoint.="?url={url}"; + $this->xmlEndpoint=preg_replace("/\{format\}/","xml",$endpoint); + $this->xmlEndpoint.="?url={url}"; + } else { + $this->jsonEndpoint=$endpoint."?url={url}&format=json"; + $this->xmlEndpoint=$endpoint."?url={url}&format=xml"; + } + if ($this->dimensionsSupported) { + if (!empty($this->maxwidth)) { + $this->jsonEndpoint.= '&maxwidth=' . $this->maxwidth; + $this->xmlEndpoint.= '&maxwidth=' . $this->maxwidth; + } + if (!empty($this->maxheight)) { + $this->jsonEndpoint.= '&maxwidth=' . $this->maxheight; + $this->xmlEndpoint.= '&maxwidth=' . $this->maxheight; + } + } + } + + public function getUrlRegExp(){ return $this->urlRegExp; } + public function getJsonEndpoint(){ return $this->jsonEndpoint; } + public function getXmlEndpoint(){ return $this->xmlEndpoint; } + + public function match($url){ + return preg_match($this->urlRegExp,$url); + } + private function file_get_contents($fileurl) { + $allow_curl = defined('OEMBED_USE_CURL') && OEMBED_USE_CURL && defined('CURLOPT_URL'); + return CurlFetcher::file_get_contents($fileurl, $allow_curl); + } + private function provideXML($url){ + return $this->file_get_contents(preg_replace("/\{url\}/",urlencode($url),$this->xmlEndpoint)); + } + private function getTypeObj($type){ + switch($type){ + case "image": + case "photo": + return new PhotoEmbed(); + break; + case "video": + return new VideoEmbed(); + break; + case "link": + return new LinkEmbed(); + break; + case "rich": + return new RichEmbed(); + break; + default: + return new OEmbed(); + } + } + private function provideObject($url){ + if (!$this->onlyJson) { + $xml=simplexml_load_string($this->provideXML($url)); + } + else { + $data=$this->provide($url); + if (!empty($data)) $xml = json_decode($data); + } + //TODO $xml->type alapjan assigner + $obj = $this->getTypeObj((string)$xml->type); + $obj->cloneObj($xml); + $obj->resource_url=$url; + return $obj; + } + private function provideSerialized($url){ + $serialized=serialize($this->provideObject($url)); + return $serialized; + } + public function provide($url,$format="json"){ + if($format=="xml"){ + return $this->provideXML($url); + } else if ($format=="object"){ + return $this->provideObject($url); + } else if ($format=="serialized"){ + return $this->provideSerialized($url); + } else { + return $this->file_get_contents(preg_replace("/\{url\}/",urlencode($url),$this->jsonEndpoint)); + } + } + public function register(){} +} + diff --git a/serendipity_event_oembed/oembed/PhotoEmbed.class.php b/serendipity_event_oembed/oembed/PhotoEmbed.class.php new file mode 100644 index 00000000..fa2587c5 --- /dev/null +++ b/serendipity_event_oembed/oembed/PhotoEmbed.class.php @@ -0,0 +1,6 @@ +provider as $provider){ + if (isset($provider->name)) { + $pentry = $provider->name; + if ($with_url && isset($provider->url)) { + $pentry = "$pentry
(" . $provider->url . ")"; + } + $provider_names[] = $pentry; + } + } + natsort($provider_names); + return "
  1. " . implode("
  2. ", $provider_names) . "
"; + } +} \ No newline at end of file diff --git a/serendipity_event_oembed/oembed/ProviderManager.class.php b/serendipity_event_oembed/oembed/ProviderManager.class.php new file mode 100644 index 00000000..92691a08 --- /dev/null +++ b/serendipity_event_oembed/oembed/ProviderManager.class.php @@ -0,0 +1,37 @@ +providers=array(); + $xml = simplexml_load_file(PLUGIN_OEMBED_PROVIDER_XML_FILE);// PROVIDER_XML comes from config.php + foreach($xml->provider as $provider){ + if(!isset($provider->class) && isset($provider->endpoint)){ + $onlyJson = isset($provider->jsononly); + $dimensionsSupported = !isset($provider->nodimensionsupport); + $this->register(new OEmbedProvider($provider->url,$provider->endpoint, $onlyJson, $maxwidth, $maxheight, $dimensionsSupported)); + } else { + $classname="".$provider->class; // force to be string :) + $reflection = new ReflectionClass($classname); + $this->register($reflection->newInstance($provider));//so we could pass config vars + } + } + } + static function getInstance($maxwidth=null, $maxheight=null){ + if(!isset($_instance) || $_instance==null){ + $_instance = new ProviderManager($maxwidth, $maxheight); + } + return $_instance; + } + public function register($provider){ + $this->providers[]=$provider; + } + public function provide($url,$format){ + foreach ($this->providers as $provider){ + if ($provider->match($url)){ + return $provider->provide($url,$format); + } + } + return null; + } +} diff --git a/serendipity_event_oembed/oembed/RichEmbed.class.php b/serendipity_event_oembed/oembed/RichEmbed.class.php new file mode 100644 index 00000000..cf49705b --- /dev/null +++ b/serendipity_event_oembed/oembed/RichEmbed.class.php @@ -0,0 +1,6 @@ +type='video'; + $myEmbed->version='1.0'; + $myEmbed->provider_name="Youtube"; + $myEmbed->provider_url="http://youtube.com"; + $myEmbed->resource_url=$url; + $xml = new DOMDocument; + if(@($xml->load('http://gdata.youtube.com/feeds/api/videos/'.$video_id))) { + @$guid = $xml->getElementsByTagName("guid")->item(0)->nodeValue; + $link = str_replace("http://www.youtube.com/watch?v=","http://bergengocia.net/indavideobombyoutubemashup/view.php?id=",$guid); + $myEmbed->title =$xml->getElementsByTagName("title")->item(0)->nodeValue; + $myEmbed->description =$xml->getElementsByTagNameNS("*","description")->item(0)->nodeValue; + $myEmbed->author_name =$xml->getElementsByTagName("author")->item(0)->getElementsByTagName("name")->item(0)->nodeValue; + $myEmbed->author_url =$xml->getElementsByTagName("author")->item(0)->getElementsByTagName("uri")->item(0)->nodeValue; + $myEmbed->thumbnail_url =$xml->getElementsByTagNameNS("*","thumbnail")->item(0)->getAttribute("url"); + $myEmbed->thumbnail_width =$xml->getElementsByTagNameNS("*","thumbnail")->item(0)->getAttribute("width"); + $myEmbed->thumbnail_height =$xml->getElementsByTagNameNS("*","thumbnail")->item(0)->getAttribute("height"); + $med_content_url=$xml->getElementsByTagNameNS("http://search.yahoo.com/mrss/","content")->item(0)->getAttribute("url"); + $myEmbed->html= + ''."\n". + ' '."\n". + ' '."\n". + ' '."\n". + ''; // according to http://code.google.com/apis/youtube/developers_guide_protocol.html#Displaying_information_about_a_video + $myEmbed->width="425"; + $myEmbed->height="350"; // same as in the html + //$myEmbed->duration=$xml->getElementsByTagNameNS($xml->lookupNamespaceURI("*"),"content")->item(0)->getAttribute("duration"); + //$time = floor($duration / 60) . ":" . $duration % 60; + return $myEmbed; + } else throw new Exception404("xxx"); + } + private function provideXML($url){ + $string=""; + foreach($this->getEmbed($url) as $key=>$value){ + if(isset($value)&& $value!="") $string.=" <".$key.">".$value."\n"; + } + $string="\n".$string.""; + return $string; + } + private function provideObject($url){ + return $this->getEmbed($url); + } + private function provideJSON($url){ + return json_encode($this->getEmbed($url)); + } + private function provideSerialized($url){ + return serialize($this->getEmbed($url)); + } + public function provide($url,$format="json"){ + if($format=="xml"){ + return $this->provideXML($url); + } else if ($format=="object"){ + return $this->provideObject($url); + } else if ($format=="serialized"){ + return $this->provideSerialized($url); + } else { + return $this->provideJSON($url);; + } + } + + + public function __construct($config,$maxwidth=null, $maxheight=null){ + parent::__construct("http://youtube.com","", $maxwidth, $maxheight); + } +} diff --git a/serendipity_event_oembed/oembed/config.php b/serendipity_event_oembed/oembed/config.php new file mode 100644 index 00000000..7ddc4bf6 --- /dev/null +++ b/serendipity_event_oembed/oembed/config.php @@ -0,0 +1,29 @@ +\n"; + @include $filename; +} +*/ +require_once dirname(__FILE__) . '/' . 'Exception404.class.php'; +require_once dirname(__FILE__) . '/' . 'OEmbed.class.php'; +require_once dirname(__FILE__) . '/' . 'LinkEmbed.class.php'; +require_once dirname(__FILE__) . '/' . 'PhotoEmbed.class.php'; +require_once dirname(__FILE__) . '/' . 'RichEmbed.class.php'; +require_once dirname(__FILE__) . '/' . 'VideoEmbed.class.php'; + +require_once dirname(__FILE__) . '/' . 'EmbedProvider.class.php'; +require_once dirname(__FILE__) . '/' . 'OEmbedProvider.class.php'; + +// Will be loaded via generic oembedprovider! +//require_once dirname(__FILE__) . '/' . 'YouTubeProvider.class.php'; + +require_once dirname(__FILE__) . '/' . 'ProviderManager.class.php'; + diff --git a/serendipity_event_oembed/oembed/providers.xml b/serendipity_event_oembed/oembed/providers.xml new file mode 100644 index 00000000..2f8a73cf --- /dev/null +++ b/serendipity_event_oembed/oembed/providers.xml @@ -0,0 +1,205 @@ + + + + Flickr (image and video) + http://*.flickr.com/* + http://www.flickr.com/services/oembed/ + + + + Twitter Status + https?://*.twitter.com/*/status(es)?/* + https://api.twitter.com/1/statuses/oembed.{format} + + + http://*.vimeo.com/* + http://vimeo.com/api/oembed.{format} + + + + Youtube + http://*.youtube.com/* + http://www.youtube.com/oembed + + + Youtube short link + http://*.youtu.be/* + http://www.youtube.com/oembed + + + SmugMug + http://*.smugmug.com/* + http://api.smugmug.com/services/oembed/ + + + Photobucket + http://*.photobucket.com/(albums|groups)/* + http://photobucket.com/oembed + + + + Official.fm (tracks and playlist) + http://official.fm/(playlists|tracks)/* + http://official.fm/services/oembed.{format} + + + + Blib TV + http://blip.tv/* + + http://blip.tv/oembed + + + + Qik Mobile Videos + http://qik.com/video/* + http://qik.com/api/oembed.{format} + + + + My Opera + + http://my.opera.com/* + http://my.opera.com/service/oembed + + + + Hulu + http://www.hulu.com/* + http://www.hulu.com/api/oembed.{format} + + + Revision 3 + http://*.revision3.com/* + http://revision3.com/api/oembed/ + + + Viddler + http://*.viddler.com/* + http://lab.viddler.com/services/oembed/ + + + + YFrog + + http://*.yfrog.com/* + http://www.yfrog.com/api/oembed + + + + Instragr.am + + http://*.instagr.am/* + http://api.instagram.com/api/v1/oembed/ + + + + DailyMotion + http://*.dailymotion.com/* + http://www.dailymotion.com/services/oembed + + + + PicPlz + + http://*.picplz.com/* + http://picplz.com/oembed + + + + SoundCloud + http://*.soundcloud.com/* + http://soundcloud.com/oembed + + + Skitch + http://(www.)?skitch.com/* + http://skitch.com/oembed/ + + + + + + + Twitpic (via noembed.com) + + http://(www.)?twitpic.com/* + http://noembed.com/embed + + + Imgur.com (via noembed.com) + + http://imgur.com/* + http://noembed.com/embed + + + Imdb.com (via noembed.com) + + http://(www.)?imdb.com/title/* + http://noembed.com/embed + + + CloudApp (via noembed.com) + + http://cl.ly/* + http://noembed.com/embed + + + ASCII Art Farts (via noembed.com) + + http://www.asciiartfarts.com/*.html + http://noembed.com/embed + + + GiantBomb (via noembed.com) + + http://www.giantbomb.com/* + http://noembed.com/embed + + + Spotify (via noembed.com) + + https?://open.spotify.com/(track|album)/* + http://noembed.com/embed + + + + + + Audioboo (via oohembed.com) + + http://((www.)?audio)?boo.fm/boos/* + http://oohembed.com/oohembed/ + + + Wikipedia (via oohembed.com) + + https?://*.wikipedia.org/wiki/* + http://oohembed.com/oohembed/ + + + diff --git a/serendipity_event_oembed/oembed/tests/OEmbedTest.php b/serendipity_event_oembed/oembed/tests/OEmbedTest.php new file mode 100644 index 00000000..40f0ab61 --- /dev/null +++ b/serendipity_event_oembed/oembed/tests/OEmbedTest.php @@ -0,0 +1,24 @@ +provider as $provider){ + // $x = new OEmbedProvider("http://*.flickr.com/*","http://www.flickr.com/services/oembed/"); + $x = new OEmbedProvider($provider->url,$provider->endpoint); + echo $x->url.":\n"; + if ($x->match("http://www.flickr.com/photos/bees/2341623661/")){ + print_r($x->provide("http://www.flickr.com/photos/bees/2341623661/","object")); + } + echo " ".$x->getUrlRegExp()."\n"; + echo " ".$x->getJsonEndpoint()."\n"; + echo " ".$x->getXmlEndpoint()."\n"; +} diff --git a/serendipity_event_oembed/oembed/tests/ProviderManagerTest.php b/serendipity_event_oembed/oembed/tests/ProviderManagerTest.php new file mode 100644 index 00000000..0ee1ae52 --- /dev/null +++ b/serendipity_event_oembed/oembed/tests/ProviderManagerTest.php @@ -0,0 +1,24 @@ +provide($url,"object"); + if (!empty($obj)) print_r($obj); +} + +$manager = ProviderManager::getInstance(); +// Youtube long link +//test($manager,"http://www.youtube.com/watch?v=8UVNT4wvIGY"); + // Youtube Kurze URL +//test($manager,"http://youtu.be/8UVNT4wvIGY"); +// Twitter +//test($manager,"https://twitter.com/#!/tagesschau/status/146562892454572032"); +// flickr +test($manager,"http://www.flickr.com/photos/gbrockhaus/2052855443/in/set-72157603214268227/"); +// vimeo +//test($manager,"http://vimeo.com/33510073"); + diff --git a/serendipity_event_oembed/oembed/tests/ProviderXmlTest.php b/serendipity_event_oembed/oembed/tests/ProviderXmlTest.php new file mode 100644 index 00000000..64aaaffc --- /dev/null +++ b/serendipity_event_oembed/oembed/tests/ProviderXmlTest.php @@ -0,0 +1,8 @@ +provider as $provider){ + echo $provider->url; + echo $provider->endpoint; +} + diff --git a/serendipity_event_oembed/oembed/tests/YouTubeTest.php b/serendipity_event_oembed/oembed/tests/YouTubeTest.php new file mode 100644 index 00000000..654c8315 --- /dev/null +++ b/serendipity_event_oembed/oembed/tests/YouTubeTest.php @@ -0,0 +1,12 @@ +provide("","object"); + //print_r($obj); + print_r($obj->html); +} + +testYoutubeProvider(); + diff --git a/serendipity_event_oembed/serendipity_event_oembed.php b/serendipity_event_oembed/serendipity_event_oembed.php new file mode 100644 index 00000000..3d4b6ae6 --- /dev/null +++ b/serendipity_event_oembed/serendipity_event_oembed.php @@ -0,0 +1,160 @@ +add('name', PLUGIN_EVENT_OEMBED_NAME); + $propbag->add('description', PLUGIN_EVENT_OEMBED_DESC); + $propbag->add('stackable', false); + $propbag->add('author', 'Grischa Brockhaus'); + $propbag->add('version', '1.00'); + $propbag->add('requirements', array( + 'serendipity' => '0.8', + 'smarty' => '2.6.7', + 'php' => '5.1.0' + )); + $propbag->add('groups', array('FRONTEND_EXTERNAL_SERVICES')); + $propbag->add('event_hooks', array( + 'frontend_display' => true, + )); + $configuration = $configuration = array('info','maxwidth','maxheight'); + $propbag->add('configuration', $configuration); + } + + function introspect_config_item($name, &$propbag) + { + switch($name) { + case 'info': + $propbag->add('type', 'content'); + $propbag->add('default', sprintf(PLUGIN_EVENT_OEMBED_INFO, ProviderList::ul_providernames(true))); + break; + case 'maxwidth': + $propbag->add('type', 'string'); + $propbag->add('name', PLUGIN_EVENT_OEMBED_MAXWIDTH); + $propbag->add('description', PLUGIN_EVENT_OEMBED_MAXWIDTH_DESC); + $propbag->add('default', ''); + break; + case 'maxheight': + $propbag->add('type', 'string'); + $propbag->add('name', PLUGIN_EVENT_OEMBED_MAXHEIGHT); + $propbag->add('description', PLUGIN_EVENT_OEMBED_MAXHEIGHT_DESC); + $propbag->add('default', ''); + break; + } + return true; + } + + function event_hook($event, &$bag, &$eventData) { + global $serendipity; + + static $simplePatterns = null; + + if ($simplePatterns==null) { + $simplePatterns = array( + //'simpleTweet' => '@\(tweet\s+(\S*)\)@Usi', + 'simpleTweet' => '@\[(?:e|embed)\s+(.*)\]@Usi', + ); + } + + $hooks = &$bag->get('event_hooks'); + + if (isset($hooks[$event])) { + switch($event) { + case 'frontend_display': + if (isset($eventData['body']) && isset($eventData['extended'])) { + $this->update_entry($eventData, $simplePatterns, 'body'); + $this->update_entry($eventData, $simplePatterns, 'extended'); + } + return true; + } + } + + return true; + + } + + function update_entry(&$eventData, &$patterns, $dateType) { + if (!empty($eventData[$dateType])) { + $eventData[$dateType] = preg_replace_callback( + $patterns['simpleTweet'], + array( $this, "oembedRewriteCallback"), + $eventData[$dateType]); + } + } + + function oembedRewriteCallback($match) { + $url = $match[1]; + $maxwidth = $this->get_config('maxwidth',''); + $maxheight = $this->get_config('maxheight',''); + $obj = $this->expand($url, $maxwidth, $maxheight); + return OEmbedTemplater::fetchTemplate('oembed.tpl',$obj, $url); + } + + /** + * This method can be used by other plugins. It will expand an URL to an oembed object (or null if not supported). + * @param string $url The url to be expanded + * @param string $maxwidth Maximum width of returned object (if service supports this). May be left empty + * @param string $maxheight Maximum height of returned object (if service supports this). May be left empty + * @return OEmbed or null + */ + function expand($url, $maxwidth=null, $maxheight=null) { + $obj = OEmbedDatabase::load_oembed($url); + if (empty($obj)) { + $manager = ProviderManager::getInstance($maxwidth,$maxheight); + try { + $obj=$manager->provide($url,"object"); + if (isset($obj)) { + $obj = OEmbedDatabase::save_oembed($url,$obj); + } + } + catch (ErrorException $e) { + // Timeout in most cases + //return $e; + } + } + return $obj; + } + + function cleanup_html( $str ) { + // Clear unicode stuff + $str=str_ireplace("\u003C","<",$str); + $str=str_ireplace("\u003E",">",$str); + // Clear CDATA Trash. + $str = preg_replace("@^$@", '$1', $str); + $str = preg_replace("@^$@", '$1', $str); + return $str; + } + function cleanup() { + OEmbedDatabase::install($this); + OEmbedDatabase::clear_cache(); + echo '
Cleared oembed cache.
'; + } + function install() { + OEmbedDatabase::install($this); + } + +} \ No newline at end of file diff --git a/serendipity_plugin_twitter/serendipity_event_twitter.php b/serendipity_plugin_twitter/serendipity_event_twitter.php index 667a875a..7fb6dbf1 100644 --- a/serendipity_plugin_twitter/serendipity_event_twitter.php +++ b/serendipity_plugin_twitter/serendipity_event_twitter.php @@ -625,7 +625,7 @@ class serendipity_event_twitter extends serendipity_plugin { $propbag->add('name', PLUGIN_EVENT_TWITTER_CONSUMER_KEY); $propbag->add('description', PLUGIN_EVENT_TWITTER_CONSUMER_KEY_DESC); $propbag->add('default', ''); - break; + break; case 'general_oa_consumersecret': $propbag->add('type', 'string'); $propbag->add('name', PLUGIN_EVENT_TWITTER_CONSUMER_SECRET); @@ -1245,7 +1245,7 @@ a.twitter_update_time { } if (empty($highest_ids[$article_id]['last_info']) || empty($highest_ids[$article_id]['last_info']['lasttweetid']) || "{$entry[TWITTER_SEARCHRESULT_ID]}">$highest_ids[$article_id]['last_info']['lasttweetid']) { if ($complete) { // This is called from admin interface - echo "Found new tweetback for article $article_id: tweetid: {$entry[TWITTER_SEARCHRESULT_ID]}
"; + echo "
Found new tweetback for article $article_id: tweetid: {$entry[TWITTER_SEARCHRESULT_ID]}

"; } $this->check_tweetbacks_save_comment($article_id, $entry, $comment_type, true); $comment_saved = true;