From 0aeea42724b7eac2bd2cd78b9d740fe5491d8df4 Mon Sep 17 00:00:00 2001 From: Craig Andrews Date: Wed, 15 Jul 2009 10:29:54 -0400 Subject: [PATCH 1/6] Added stub oembed api endpoint --- actions/api.php | 1 + actions/twitapilaconica.php | 8 ++++++++ lib/router.php | 4 ++++ 3 files changed, 13 insertions(+) diff --git a/actions/api.php b/actions/api.php index 452ed8e824..fa5a7e7ae9 100644 --- a/actions/api.php +++ b/actions/api.php @@ -129,6 +129,7 @@ class ApiAction extends Action 'laconica/config', 'laconica/wadl', 'tags/timeline', + 'laconica/oembed', 'groups/timeline'); static $bareauth = array('statuses/user_timeline', diff --git a/actions/twitapilaconica.php b/actions/twitapilaconica.php index 8cd7a64b9f..ec40bc6273 100644 --- a/actions/twitapilaconica.php +++ b/actions/twitapilaconica.php @@ -171,4 +171,12 @@ class TwitapilaconicaAction extends TwitterapiAction parent::handle($args); $this->serverError(_('API method under construction.'), 501); } + + function oembed($args, $apidata) + { + parent::handle($args); + $url = $args['url']; + print_r($apidata); + die("oembed!"); + } } diff --git a/lib/router.php b/lib/router.php index e121386370..652d2a2663 100644 --- a/lib/router.php +++ b/lib/router.php @@ -390,6 +390,10 @@ class Router // laconica + $m->connect('api/laconica/:method', + array('action' => 'api', + 'apiaction' => 'laconica')); + $m->connect('api/laconica/:method', array('action' => 'api', 'apiaction' => 'laconica')); From e637e5a8a97d5a30710046e70b1994007d65b939 Mon Sep 17 00:00:00 2001 From: Craig Andrews Date: Wed, 15 Jul 2009 14:49:41 -0400 Subject: [PATCH 2/6] Support oembed for attachments and notices --- actions/twitapilaconica.php | 117 +++++++++++++++++++++++++++++++++++- 1 file changed, 115 insertions(+), 2 deletions(-) diff --git a/actions/twitapilaconica.php b/actions/twitapilaconica.php index ec40bc6273..114dff6eed 100644 --- a/actions/twitapilaconica.php +++ b/actions/twitapilaconica.php @@ -175,8 +175,121 @@ class TwitapilaconicaAction extends TwitterapiAction function oembed($args, $apidata) { parent::handle($args); + + common_debug("in oembed api action"); + + $this->auth_user = $apidata['user']; + $url = $args['url']; - print_r($apidata); - die("oembed!"); + if( substr(strtolower($url),0,strlen(common_root_url())) == strtolower(common_root_url()) ){ + $path = substr($url,strlen(common_root_url())); + + $r = Router::get(); + + $proxy_args = $r->map($path); + + if (!$proxy_args) { + $this->serverError(_("$path not found"), 404); + } + $oembed=array(); + $oembed['version']='1.0'; + $oembed['provider_name']=common_config('site', 'name'); + $oembed['provider_url']=common_root_url(); + switch($proxy_args['action']){ + case 'shownotice': + $oembed['type']='link'; + $id = $proxy_args['notice']; + $notice = Notice::staticGet($id); + if(empty($notice)){ + $this->serverError(_("notice $id not found"), 404); + } + $profile = $notice->getProfile(); + if (empty($profile)) { + $this->serverError(_('Notice has no profile'), 500); + } + if (!empty($profile->fullname)) { + $authorname = $profile->fullname . ' (' . $profile->nickname . ')'; + } else { + $authorname = $profile->nickname; + } + $oembed['title'] = sprintf(_('%1$s\'s status on %2$s'), + $authorname, + common_exact_date($notice->created)); + $oembed['author_name']=$authorname; + $oembed['author_url']=$profile->profileurl; + $oembed['url']=($notice->url?$notice->url:$notice->uri); + $oembed['html']=$notice->rendered; + break; + case 'attachment': + $id = $proxy_args['attachment']; + $attachment = File::staticGet($id); + if(empty($attachment)){ + $this->serverError(_("attachment $id not found"), 404); + } + if(empty($attachment->filename) && $file_oembed = File_oembed::staticGet('file_id', $attachment->id)){ + // Proxy the existing oembed information + $oembed['type']=$file_oembed->type; + $oembed['provider']=$file_oembed->provider; + $oembed['provider_url']=$file_oembed->provider_url; + $oembed['width']=$file_oembed->width; + $oembed['height']=$file_oembed->height; + $oembed['html']=$file_oembed->html; + $oembed['title']=$file_oembed->title; + $oembed['author_name']=$file_oembed->author_name; + $oembed['author_url']=$file_oembed->author_url; + $oembed['url']=$file_oembed->url; + }else if(substr($attachment->mimetype,0,strlen('image/'))=='image/'){ + $oembed['type']='photo'; + //TODO set width and height + //$oembed['width']= + //$oembed['height']= + $oembed['url']=$attachment->url; + }else{ + $oembed['type']='link'; + $oembed['url']=common_local_url('attachment', + array('attachment' => $attachment->id)); + } + if($attachment->title) $oembed['title']=$attachment->title; + break; + default: + $this->serverError(_("$path not supported for oembed requests"), 501); + } + + switch($apidata['content-type']){ + case 'xml': + $this->init_document('xml'); + $this->elementStart('oembed'); + $this->element('version',null,$oembed['version']); + $this->element('type',null,$oembed['type']); + if($oembed['provider_name']) $this->element('provider_name',null,$oembed['provider_name']); + if($oembed['provider_url']) $this->element('provider_url',null,$oembed['provider_url']); + if($oembed['title']) $this->element('title',null,$oembed['title']); + if($oembed['author_name']) $this->element('author_name',null,$oembed['author_name']); + if($oembed['author_url']) $this->element('author_url',null,$oembed['author_url']); + if($oembed['url']) $this->element('url',null,$oembed['url']); + if($oembed['html']) $this->element('html',null,$oembed['html']); + if($oembed['width']) $this->element('width',null,$oembed['width']); + if($oembed['height']) $this->element('height',null,$oembed['height']); + if($oembed['cache_age']) $this->element('cache_age',null,$oembed['cache_age']); + if($oembed['thumbnail_url']) $this->element('thumbnail_url',null,$oembed['thumbnail_url']); + if($oembed['thumbnail_width']) $this->element('thumbnail_width',null,$oembed['thumbnail_width']); + if($oembed['thumbnail_height']) $this->element('thumbnail_height',null,$oembed['thumbnail_height']); + + + $this->elementEnd('oembed'); + $this->end_document('xml'); + break; + case 'json': + $this->init_document('json'); + print(json_encode($oembed)); + $this->end_document('json'); + break; + default: + $this->serverError(_('content type ' . $apidata['content-type'] . ' not supported'), 501); + } + + }else{ + $this->serverError(_('Only ' . common_root_url() . ' urls over plain http please'), 404); + } } } From 6308539c1d669ad0b6072b48deeaa95969ebe318 Mon Sep 17 00:00:00 2001 From: Craig Andrews Date: Wed, 15 Jul 2009 15:11:29 -0400 Subject: [PATCH 3/6] Added oEmbed discovery for attachments and notices --- actions/attachment.php | 22 ++++++++++++++++++++++ actions/shownotice.php | 14 ++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/actions/attachment.php b/actions/attachment.php index ee4cd9640d..c9c416cb5b 100644 --- a/actions/attachment.php +++ b/actions/attachment.php @@ -98,6 +98,28 @@ class AttachmentAction extends Action return $a->title(); } + function extraHead() + { + $this->element('link',array('rel'=>'alternate', + 'type'=>'application/json+oembed', + 'href'=>common_local_url( + 'api', + array('apiaction'=>'laconica','method'=>'oembed.json'), + array('url'=> + common_local_url('attachment', + array('attachment' => $this->attachment->id)))), + 'title'=>'oEmbed'),null); + $this->element('link',array('rel'=>'alternate', + 'type'=>'text/xml+oembed', + 'href'=>common_local_url( + 'api', + array('apiaction'=>'laconica','method'=>'oembed.xml'), + array('url'=> + common_local_url('attachment', + array('attachment' => $this->attachment->id)))), + 'title'=>'oEmbed'),null); + } + /** * Handle input * diff --git a/actions/shownotice.php b/actions/shownotice.php index 1ec38a76bc..4cf226f1cf 100644 --- a/actions/shownotice.php +++ b/actions/shownotice.php @@ -275,6 +275,20 @@ class ShownoticeAction extends OwnerDesignAction $this->element('meta', array('name' => 'microid', 'content' => $id->toString())); } + $this->element('link',array('rel'=>'alternate', + 'type'=>'application/json+oembed', + 'href'=>common_local_url( + 'api', + array('apiaction'=>'laconica','method'=>'oembed.json'), + array('url'=>$this->notice->uri)), + 'title'=>'oEmbed'),null); + $this->element('link',array('rel'=>'alternate', + 'type'=>'text/xml+oembed', + 'href'=>common_local_url( + 'api', + array('apiaction'=>'laconica','method'=>'oembed.xml'), + array('url'=>$this->notice->uri)), + 'title'=>'oEmbed'),null); } } From f75932601c08cdbdf68fddc7b5f9871b64d841ec Mon Sep 17 00:00:00 2001 From: Craig Andrews Date: Wed, 15 Jul 2009 17:09:11 -0400 Subject: [PATCH 4/6] Fixed bugs in oEmbed library's discovery routines --- extlib/Services/oEmbed.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extlib/Services/oEmbed.php b/extlib/Services/oEmbed.php index 5d38ed883d..7d507b6f62 100644 --- a/extlib/Services/oEmbed.php +++ b/extlib/Services/oEmbed.php @@ -162,7 +162,7 @@ class Services_oEmbed } if ($this->options[self::OPTION_API] === null) { - $this->options[self::OPTION_API] = $this->discover(); + $this->options[self::OPTION_API] = $this->discover($url); } } @@ -319,7 +319,7 @@ class Services_oEmbed } } - return (isset($ret['json']) ? $ret['json'] : array_pop($ret)); + return (isset($ret['application/json']) ? $ret['application/json'] : array_pop($ret)); } /** From a35794e3c3bd147d3344eaad4b669f45595a3df5 Mon Sep 17 00:00:00 2001 From: Craig Andrews Date: Wed, 15 Jul 2009 17:10:36 -0400 Subject: [PATCH 5/6] Try oEmbed discovery before using oohembed --- classes/File.php | 5 ++-- classes/File_oembed.php | 55 +++++++++++++++++++++++--------------- classes/File_thumbnail.php | 6 ++--- 3 files changed, 39 insertions(+), 27 deletions(-) diff --git a/classes/File.php b/classes/File.php index 56d9f98278..68d385d1ea 100644 --- a/classes/File.php +++ b/classes/File.php @@ -79,9 +79,8 @@ class File extends Memcached_DataObject if (isset($redir_data['type']) && ('text/html' === substr($redir_data['type'], 0, 9)) - && ($oembed_data = File_oembed::_getOembed($given_url)) - && isset($oembed_data['json'])) { - File_oembed::saveNew($oembed_data['json'], $file_id); + && ($oembed_data = File_oembed::_getOembed($given_url))) { + File_oembed::saveNew($oembed_data, $file_id); } return $x; } diff --git a/classes/File_oembed.php b/classes/File_oembed.php index 69230e4a48..bbf112729b 100644 --- a/classes/File_oembed.php +++ b/classes/File_oembed.php @@ -56,33 +56,46 @@ class File_oembed extends Memcached_DataObject return array(false, false, false); } - function _getOembed($url, $maxwidth = 500, $maxheight = 400, $format = 'json') { - $cmd = common_config('oohembed', 'endpoint') . '?url=' . urlencode($url); - if (is_int($maxwidth)) $cmd .= "&maxwidth=$maxwidth"; - if (is_int($maxheight)) $cmd .= "&maxheight=$maxheight"; - if (is_string($format)) $cmd .= "&format=$format"; - $oe = @file_get_contents($cmd); - if (false === $oe) return false; - return array($format => (('json' === $format) ? json_decode($oe, true) : $oe)); + function _getOembed($url, $maxwidth = 500, $maxheight = 400) { + require_once INSTALLDIR.'/extlib/Services/oEmbed.php'; + $parameters = array( + 'maxwidth'=>$maxwidth, + 'maxheight'=>$maxheight, + ); + try{ + $oEmbed = new Services_oEmbed($url); + $object = $oEmbed->getObject($parameters); + return $object; + }catch(Exception $e){ + try{ + $oEmbed = new Services_oEmbed($url, array( + Services_oEmbed::OPTION_API => common_config('oohembed', 'endpoint') + )); + $object = $oEmbed->getObject($parameters); + return $object; + }catch(Exception $ex){ + return false; + } + } } function saveNew($data, $file_id) { $file_oembed = new File_oembed; $file_oembed->file_id = $file_id; - $file_oembed->version = $data['version']; - $file_oembed->type = $data['type']; - if (!empty($data['provider_name'])) $file_oembed->provider = $data['provider_name']; - if (!isset($file_oembed->provider) && !empty($data['provide'])) $file_oembed->provider = $data['provider']; - if (!empty($data['provide_url'])) $file_oembed->provider_url = $data['provider_url']; - if (!empty($data['width'])) $file_oembed->width = intval($data['width']); - if (!empty($data['height'])) $file_oembed->height = intval($data['height']); - if (!empty($data['html'])) $file_oembed->html = $data['html']; - if (!empty($data['title'])) $file_oembed->title = $data['title']; - if (!empty($data['author_name'])) $file_oembed->author_name = $data['author_name']; - if (!empty($data['author_url'])) $file_oembed->author_url = $data['author_url']; - if (!empty($data['url'])) $file_oembed->url = $data['url']; + $file_oembed->version = $data->version; + $file_oembed->type = $data->type; + if (!empty($data->provider_name)) $file_oembed->provider = $data->provider_name; + if (!empty($data->provider)) $file_oembed->provider = $data->provider; + if (!empty($data->provide_url)) $file_oembed->provider_url = $data->provider_url; + if (!empty($data->width)) $file_oembed->width = intval($data->width); + if (!empty($data->height)) $file_oembed->height = intval($data->height); + if (!empty($data->html)) $file_oembed->html = $data->html; + if (!empty($data->title)) $file_oembed->title = $data->title; + if (!empty($data->author_name)) $file_oembed->author_name = $data->author_name; + if (!empty($data->author_url)) $file_oembed->author_url = $data->author_url; + if (!empty($data->url)) $file_oembed->url = $data->url; $file_oembed->insert(); - if (!empty($data['thumbnail_url'])) { + if (!empty($data->thumbnail_url)) { File_thumbnail::saveNew($data, $file_id); } } diff --git a/classes/File_thumbnail.php b/classes/File_thumbnail.php index 44b92a2fad..0b09c6af8c 100644 --- a/classes/File_thumbnail.php +++ b/classes/File_thumbnail.php @@ -51,9 +51,9 @@ class File_thumbnail extends Memcached_DataObject function saveNew($data, $file_id) { $tn = new File_thumbnail; $tn->file_id = $file_id; - $tn->url = $data['thumbnail_url']; - $tn->width = intval($data['thumbnail_width']); - $tn->height = intval($data['thumbnail_height']); + $tn->url = $data->thumbnail_url; + $tn->width = intval($data->thumbnail_width); + $tn->height = intval($data->thumbnail_height); $tn->insert(); } } From 9ed117dc3a405175359d0a541dddfb14cdf15d47 Mon Sep 17 00:00:00 2001 From: Craig Andrews Date: Fri, 17 Jul 2009 12:33:12 -0400 Subject: [PATCH 6/6] Move the oembed endpoint to /main/oembed --- actions/api.php | 2 +- actions/attachment.php | 4 +- actions/shownotice.php | 4 +- actions/twitapilaconica.php | 120 ------------------------------------ lib/router.php | 5 ++ 5 files changed, 10 insertions(+), 125 deletions(-) diff --git a/actions/api.php b/actions/api.php index fa5a7e7ae9..8b92889f8a 100644 --- a/actions/api.php +++ b/actions/api.php @@ -129,7 +129,7 @@ class ApiAction extends Action 'laconica/config', 'laconica/wadl', 'tags/timeline', - 'laconica/oembed', + 'oembed/oembed', 'groups/timeline'); static $bareauth = array('statuses/user_timeline', diff --git a/actions/attachment.php b/actions/attachment.php index c9c416cb5b..c6a5d0d523 100644 --- a/actions/attachment.php +++ b/actions/attachment.php @@ -104,7 +104,7 @@ class AttachmentAction extends Action 'type'=>'application/json+oembed', 'href'=>common_local_url( 'api', - array('apiaction'=>'laconica','method'=>'oembed.json'), + array('apiaction'=>'oembed','method'=>'oembed.json'), array('url'=> common_local_url('attachment', array('attachment' => $this->attachment->id)))), @@ -113,7 +113,7 @@ class AttachmentAction extends Action 'type'=>'text/xml+oembed', 'href'=>common_local_url( 'api', - array('apiaction'=>'laconica','method'=>'oembed.xml'), + array('apiaction'=>'oembed','method'=>'oembed.xml'), array('url'=> common_local_url('attachment', array('attachment' => $this->attachment->id)))), diff --git a/actions/shownotice.php b/actions/shownotice.php index 4cf226f1cf..8f73dc824a 100644 --- a/actions/shownotice.php +++ b/actions/shownotice.php @@ -279,14 +279,14 @@ class ShownoticeAction extends OwnerDesignAction 'type'=>'application/json+oembed', 'href'=>common_local_url( 'api', - array('apiaction'=>'laconica','method'=>'oembed.json'), + array('apiaction'=>'oembed','method'=>'oembed.json'), array('url'=>$this->notice->uri)), 'title'=>'oEmbed'),null); $this->element('link',array('rel'=>'alternate', 'type'=>'text/xml+oembed', 'href'=>common_local_url( 'api', - array('apiaction'=>'laconica','method'=>'oembed.xml'), + array('apiaction'=>'oembed','method'=>'oembed.xml'), array('url'=>$this->notice->uri)), 'title'=>'oEmbed'),null); } diff --git a/actions/twitapilaconica.php b/actions/twitapilaconica.php index 114dff6eed..442fdbcef2 100644 --- a/actions/twitapilaconica.php +++ b/actions/twitapilaconica.php @@ -172,124 +172,4 @@ class TwitapilaconicaAction extends TwitterapiAction $this->serverError(_('API method under construction.'), 501); } - function oembed($args, $apidata) - { - parent::handle($args); - - common_debug("in oembed api action"); - - $this->auth_user = $apidata['user']; - - $url = $args['url']; - if( substr(strtolower($url),0,strlen(common_root_url())) == strtolower(common_root_url()) ){ - $path = substr($url,strlen(common_root_url())); - - $r = Router::get(); - - $proxy_args = $r->map($path); - - if (!$proxy_args) { - $this->serverError(_("$path not found"), 404); - } - $oembed=array(); - $oembed['version']='1.0'; - $oembed['provider_name']=common_config('site', 'name'); - $oembed['provider_url']=common_root_url(); - switch($proxy_args['action']){ - case 'shownotice': - $oembed['type']='link'; - $id = $proxy_args['notice']; - $notice = Notice::staticGet($id); - if(empty($notice)){ - $this->serverError(_("notice $id not found"), 404); - } - $profile = $notice->getProfile(); - if (empty($profile)) { - $this->serverError(_('Notice has no profile'), 500); - } - if (!empty($profile->fullname)) { - $authorname = $profile->fullname . ' (' . $profile->nickname . ')'; - } else { - $authorname = $profile->nickname; - } - $oembed['title'] = sprintf(_('%1$s\'s status on %2$s'), - $authorname, - common_exact_date($notice->created)); - $oembed['author_name']=$authorname; - $oembed['author_url']=$profile->profileurl; - $oembed['url']=($notice->url?$notice->url:$notice->uri); - $oembed['html']=$notice->rendered; - break; - case 'attachment': - $id = $proxy_args['attachment']; - $attachment = File::staticGet($id); - if(empty($attachment)){ - $this->serverError(_("attachment $id not found"), 404); - } - if(empty($attachment->filename) && $file_oembed = File_oembed::staticGet('file_id', $attachment->id)){ - // Proxy the existing oembed information - $oembed['type']=$file_oembed->type; - $oembed['provider']=$file_oembed->provider; - $oembed['provider_url']=$file_oembed->provider_url; - $oembed['width']=$file_oembed->width; - $oembed['height']=$file_oembed->height; - $oembed['html']=$file_oembed->html; - $oembed['title']=$file_oembed->title; - $oembed['author_name']=$file_oembed->author_name; - $oembed['author_url']=$file_oembed->author_url; - $oembed['url']=$file_oembed->url; - }else if(substr($attachment->mimetype,0,strlen('image/'))=='image/'){ - $oembed['type']='photo'; - //TODO set width and height - //$oembed['width']= - //$oembed['height']= - $oembed['url']=$attachment->url; - }else{ - $oembed['type']='link'; - $oembed['url']=common_local_url('attachment', - array('attachment' => $attachment->id)); - } - if($attachment->title) $oembed['title']=$attachment->title; - break; - default: - $this->serverError(_("$path not supported for oembed requests"), 501); - } - - switch($apidata['content-type']){ - case 'xml': - $this->init_document('xml'); - $this->elementStart('oembed'); - $this->element('version',null,$oembed['version']); - $this->element('type',null,$oembed['type']); - if($oembed['provider_name']) $this->element('provider_name',null,$oembed['provider_name']); - if($oembed['provider_url']) $this->element('provider_url',null,$oembed['provider_url']); - if($oembed['title']) $this->element('title',null,$oembed['title']); - if($oembed['author_name']) $this->element('author_name',null,$oembed['author_name']); - if($oembed['author_url']) $this->element('author_url',null,$oembed['author_url']); - if($oembed['url']) $this->element('url',null,$oembed['url']); - if($oembed['html']) $this->element('html',null,$oembed['html']); - if($oembed['width']) $this->element('width',null,$oembed['width']); - if($oembed['height']) $this->element('height',null,$oembed['height']); - if($oembed['cache_age']) $this->element('cache_age',null,$oembed['cache_age']); - if($oembed['thumbnail_url']) $this->element('thumbnail_url',null,$oembed['thumbnail_url']); - if($oembed['thumbnail_width']) $this->element('thumbnail_width',null,$oembed['thumbnail_width']); - if($oembed['thumbnail_height']) $this->element('thumbnail_height',null,$oembed['thumbnail_height']); - - - $this->elementEnd('oembed'); - $this->end_document('xml'); - break; - case 'json': - $this->init_document('json'); - print(json_encode($oembed)); - $this->end_document('json'); - break; - default: - $this->serverError(_('content type ' . $apidata['content-type'] . ' not supported'), 501); - } - - }else{ - $this->serverError(_('Only ' . common_root_url() . ' urls over plain http please'), 404); - } - } } diff --git a/lib/router.php b/lib/router.php index 652d2a2663..bf3895bf01 100644 --- a/lib/router.php +++ b/lib/router.php @@ -113,6 +113,11 @@ class Router $m->connect('main/tagother/:id', array('action' => 'tagother')); + $m->connect('main/:method', + array('action' => 'api', + 'method' => 'oembed(.xml|.json)?', + 'apiaction' => 'oembed')); + // these take a code foreach (array('register', 'confirmaddress', 'recoverpassword') as $c) {