From 3903835cb497e9d9826d728837caa8490066d89c Mon Sep 17 00:00:00 2001 From: Grischa Brockhaus Date: Wed, 14 Dec 2011 03:10:36 +0100 Subject: [PATCH] Initial: OEmbed Plugin --- serendipity_event_oembed/lang_de.inc.php | 9 +++ serendipity_event_oembed/lang_en.inc.php | 10 +++ .../oembed/EmbedProvider.class.php | 12 +++ .../oembed/Exception404.class.php | 3 + .../oembed/LinkEmbed.class.php | 4 + .../oembed/OEmbed.class.php | 23 ++++++ .../oembed/OEmbedProvider.class.php | 74 +++++++++++++++++ .../oembed/PhotoEmbed.class.php | 6 ++ .../oembed/ProviderManager.class.php | 45 +++++++++++ .../oembed/RichEmbed.class.php | 6 ++ .../oembed/VideoEmbed.class.php | 7 ++ .../oembed/YouTubeProvider.class.php | 80 +++++++++++++++++++ serendipity_event_oembed/oembed/config.php | 10 +++ serendipity_event_oembed/oembed/providers.xml | 24 ++++++ .../oembed/tests/OEmbedTest.php | 24 ++++++ .../oembed/tests/ProviderManagerTest.php | 24 ++++++ .../oembed/tests/ProviderXmlTest.php | 8 ++ .../oembed/tests/YouTubeTest.php | 12 +++ .../serendipity_event_oembed.php | 66 +++++++++++++++ 19 files changed, 447 insertions(+) create mode 100755 serendipity_event_oembed/lang_de.inc.php create mode 100755 serendipity_event_oembed/lang_en.inc.php create mode 100644 serendipity_event_oembed/oembed/EmbedProvider.class.php create mode 100644 serendipity_event_oembed/oembed/Exception404.class.php create mode 100644 serendipity_event_oembed/oembed/LinkEmbed.class.php create mode 100644 serendipity_event_oembed/oembed/OEmbed.class.php create mode 100644 serendipity_event_oembed/oembed/OEmbedProvider.class.php create mode 100644 serendipity_event_oembed/oembed/PhotoEmbed.class.php create mode 100644 serendipity_event_oembed/oembed/ProviderManager.class.php create mode 100644 serendipity_event_oembed/oembed/RichEmbed.class.php create mode 100644 serendipity_event_oembed/oembed/VideoEmbed.class.php create mode 100644 serendipity_event_oembed/oembed/YouTubeProvider.class.php create mode 100644 serendipity_event_oembed/oembed/config.php create mode 100644 serendipity_event_oembed/oembed/providers.xml create mode 100644 serendipity_event_oembed/oembed/tests/OEmbedTest.php create mode 100644 serendipity_event_oembed/oembed/tests/ProviderManagerTest.php create mode 100644 serendipity_event_oembed/oembed/tests/ProviderXmlTest.php create mode 100644 serendipity_event_oembed/oembed/tests/YouTubeTest.php create mode 100644 serendipity_event_oembed/serendipity_event_oembed.php 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..e76e12a8 --- /dev/null +++ b/serendipity_event_oembed/lang_en.inc.php @@ -0,0 +1,10 @@ + + * 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.'); diff --git a/serendipity_event_oembed/oembed/EmbedProvider.class.php b/serendipity_event_oembed/oembed/EmbedProvider.class.php new file mode 100644 index 00000000..ad94760c --- /dev/null +++ b/serendipity_event_oembed/oembed/EmbedProvider.class.php @@ -0,0 +1,12 @@ +url = $url; + $this->endpoint = $endpoint; + } +} 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..94345e82 --- /dev/null +++ b/serendipity_event_oembed/oembed/OEmbedProvider.class.php @@ -0,0 +1,74 @@ +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"; + } + } + + 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 provideXML($url){ + return file_get_contents(preg_replace("/\{url\}/",urlencode($url),$this->xmlEndpoint)); + } + private function getTypeObj($type){ + switch($type){ + 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){ + $xml=simplexml_load_string($this->provideXML($url)); + //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 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..da482ff5 --- /dev/null +++ b/serendipity_event_oembed/oembed/PhotoEmbed.class.php @@ -0,0 +1,6 @@ +providers=array(); + $xml = simplexml_load_file(PROVIDER_XML);// PROVIDER_XML comes from config.php + foreach($xml->provider as $provider){ + if(!isset($provider->class) && isset($provider->endpoint)){ + $this->register(new OEmbedProvider($provider->url,$provider->endpoint)); + } 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(){ + if(!isset($_instance) || $_instance==null){ + $_instance = new ProviderManager(); + } + 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..18274118 --- /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){ + parent::__construct("http://youtube.com",""); + } +} diff --git a/serendipity_event_oembed/oembed/config.php b/serendipity_event_oembed/oembed/config.php new file mode 100644 index 00000000..2a1bc740 --- /dev/null +++ b/serendipity_event_oembed/oembed/config.php @@ -0,0 +1,10 @@ + diff --git a/serendipity_event_oembed/oembed/providers.xml b/serendipity_event_oembed/oembed/providers.xml new file mode 100644 index 00000000..f4ccfcca --- /dev/null +++ b/serendipity_event_oembed/oembed/providers.xml @@ -0,0 +1,24 @@ + + + + http://*.flickr.com/* + http://www.flickr.com/services/oembed/ + + + http://*.pownce.com/* + http://api.pownce.com/2.1/oembed.{format} + + + https://*.twitter.com/* + https://api.twitter.com/1/statuses/oembed.{format} + + + http://*.vimeo.com/* + http://vimeo.com/api/oembed.{format} + + + http://*.youtube.*/* + YouTubeProvider + + + 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..9ad199cd --- /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..ac8b8c24 --- /dev/null +++ b/serendipity_event_oembed/serendipity_event_oembed.php @@ -0,0 +1,66 @@ +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', '0.01'); + $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( + 'backend_publish' => true, // An entry was puplished (was draft before or saved from the scratch). + )); + + //$propbag->add('configuration', array('max_items','ext_vis_stat','stat_all','banned_bots')); + } + + function introspect_config_item($name, &$propbag) + { + } + + function event_hook($event, &$bag, &$eventData) { + global $serendipity; + + $hooks = &$bag->get('event_hooks'); + + if (isset($hooks[$event])) { + switch($event) { + case 'backend_publish': + $this->update_entry($eventData); + return true; + } + } + + return true; + + } + + function update_entry($eventData) { + + } + +} \ No newline at end of file