From 8250006fbfdc120a4766f85ff5d6ee79798d626d Mon Sep 17 00:00:00 2001 From: Craig Andrews Date: Thu, 9 Jul 2009 18:42:19 -0400 Subject: When a notice is posted with an attachment, the facebook stream update has media displayed inline, or as links. http://laconi.ca/trac/ticket/1685 --- lib/facebookaction.php | 15 ++----------- lib/facebookutil.php | 61 ++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 59 insertions(+), 17 deletions(-) (limited to 'lib') diff --git a/lib/facebookaction.php b/lib/facebookaction.php index 1ae90d53b..5be2f2fe6 100644 --- a/lib/facebookaction.php +++ b/lib/facebookaction.php @@ -460,16 +460,6 @@ class FacebookAction extends Action } } - function updateFacebookStatus($notice) - { - $prefix = $this->facebook->api_client->data_getUserPreference(FACEBOOK_NOTICE_PREFIX, $this->fbuid); - $content = "$prefix $notice->content"; - - if ($this->facebook->api_client->users_hasAppPermission('status_update', $this->fbuid)) { - $this->facebook->api_client->users_setStatus($content, $this->fbuid, false, true); - } - } - function saveNewNotice() { @@ -504,7 +494,7 @@ class FacebookAction extends Action $replyto = $this->trimmed('inreplyto'); $notice = Notice::saveNew($user->id, $content, - 'Facebook', 1, ($replyto == 'false') ? null : $replyto); + 'web', 1, ($replyto == 'false') ? null : $replyto); if (is_string($notice)) { $this->showPage($notice); @@ -514,8 +504,7 @@ class FacebookAction extends Action common_broadcast_notice($notice); // Also update the user's Facebook status - $this->updateFacebookStatus($notice); - $this->updateProfileBox($notice); + facebookBroadcastNotice($notice); } diff --git a/lib/facebookutil.php b/lib/facebookutil.php index 632ec4bad..85077c254 100644 --- a/lib/facebookutil.php +++ b/lib/facebookutil.php @@ -86,13 +86,17 @@ function isFacebookBound($notice, $flink) { // Check to see if the user has given the FB app status update perms $result = $facebook->api_client-> - users_hasAppPermission('status_update', $fbuid); + users_hasAppPermission('publish_stream', $fbuid); + if ($result != 1) { + $result = $facebook->api_client-> + users_hasAppPermission('status_update', $fbuid); + } if ($result != 1) { $user = $flink->getUser(); $msg = "Not sending notice $notice->id to Facebook " . "because user $user->nickname hasn't given the " . - 'Facebook app \'status_update\' permission.'; + 'Facebook app \'status_update\' or \'publish_stream\' permission.'; common_debug($msg); $success = false; } @@ -138,7 +142,56 @@ function facebookBroadcastNotice($notice) // Okay, we're good to go, update the FB status try { - $facebook->api_client->users_setStatus($status, $fbuid, false, true); + $result = $facebook->api_client-> + users_hasAppPermission('publish_stream', $fbuid); + if($result == 1){ + // authorized to use the stream api, so use it + $fbattachment = null; + $attachments = $notice->attachments(); + if($attachments){ + $fbattachment=array(); + $fbattachment['media']=array(); + //facebook only supports one attachment per item + $attachment = $attachments[0]; + $fbmedia=array(); + if(strncmp($attachment->mimetype,'image/',strlen('image/'))==0){ + $fbmedia['type']='image'; + $fbmedia['src']=$attachment->url; + $fbmedia['href']=$attachment->url; + $fbattachment['media'][]=$fbmedia; +/* Video doesn't seem to work. The notice never makes it to facebook, and no error is reported. + }else if(strncmp($attachment->mimetype,'video/',strlen('image/'))==0 || $attachment->mimetype="application/ogg"){ + $fbmedia['type']='video'; + $fbmedia['video_src']=$attachment->url; + // http://wiki.developers.facebook.com/index.php/Attachment_%28Streams%29 + // says that preview_img is required... but we have no value to put in it + // $fbmedia['preview_img']=$attachment->url; + if($attachment->title){ + $fbmedia['video_title']=$attachment->title; + } + $fbmedia['video_type']=$attachment->mimetype; + $fbattachment['media'][]=$fbmedia; +*/ + }else if($attachment->mimetype=='audio/mpeg'){ + $fbmedia['type']='mp3'; + $fbmedia['src']=$attachment->url; + $fbattachment['media'][]=$fbmedia; + }else if($attachment->mimetype=='application/x-shockwave-flash'){ + $fbmedia['type']='flash'; + // http://wiki.developers.facebook.com/index.php/Attachment_%28Streams%29 + // says that imgsrc is required... but we have no value to put in it + // $fbmedia['imgsrc']=''; + $fbmedia['swfsrc']=$attachment->url; + $fbattachment['media'][]=$fbmedia; + }else{ + $fbattachment['name']=($attachment->title?$attachment->title:$attachment->url); + $fbattachment['href']=$attachment->url; + } + } + $facebook->api_client->stream_publish($status, $fbattachment, null, null, $fbuid); + }else{ + $facebook->api_client->users_setStatus($status, $fbuid, false, true); + } } catch(FacebookRestClientException $e) { common_log(LOG_ERR, $e->getMessage()); common_log(LOG_ERR, @@ -150,7 +203,7 @@ function facebookBroadcastNotice($notice) if ($code >= 200) { // 200 The application does not have permission to operate on the passed in uid parameter. - // 250 Updating status requires the extended permission status_update. + // 250 Updating status requires the extended permission status_update or publish_stream. // see: http://wiki.developers.facebook.com/index.php/Users.setStatus#Example_Return_XML remove_facebook_app($flink); -- cgit v1.2.3-54-g00ecf From 08d50655f3a220b1fe970b0917a6ecbcae019b04 Mon Sep 17 00:00:00 2001 From: Craig Andrews Date: Fri, 10 Jul 2009 17:00:27 -0400 Subject: added group status api, located at /api/statuses/group_timeline/ID.rss http://laconi.ca/trac/ticket/1702 --- actions/showgroup.php | 23 +++++++++++++++--- actions/twitapistatuses.php | 58 +++++++++++++++++++++++++++++++++++++++++++++ lib/router.php | 2 +- lib/twitterapi.php | 28 ++++++++++++++++++++++ 4 files changed, 107 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/actions/showgroup.php b/actions/showgroup.php index ce11d574e..f803840ff 100644 --- a/actions/showgroup.php +++ b/actions/showgroup.php @@ -317,8 +317,25 @@ class ShowgroupAction extends GroupDesignAction common_local_url('grouprss', array('nickname' => $this->group->nickname)); - return array(new Feed(Feed::RSS1, $url, sprintf(_('Notice feed for %s group'), - $this->group->nickname))); + return array(new Feed(Feed::RSS1, + common_local_url('grouprss', + array('nickname' => $this->group->nickname)), + sprintf(_('Notice feed for %s group (RSS 1.0)'), + $this->group->nickname)), + new Feed(Feed::RSS2, + common_local_url('api', + array('apiaction' => 'statuses', + 'method' => 'group_timeline', + 'argument' => $this->group->nickname.'.rss')), + sprintf(_('Notice feed for %s group (RSS 2.0)'), + $this->group->nickname)), + new Feed(Feed::ATOM, + common_local_url('api', + array('apiaction' => 'statuses', + 'method' => 'group_timeline', + 'argument' => $this->group->nickname.'.atom')), + sprintf(_('Notice feed for %s group (Atom)'), + $this->group->nickname))); } /** @@ -466,4 +483,4 @@ class GroupAdminSection extends ProfileSection { return null; } -} \ No newline at end of file +} diff --git a/actions/twitapistatuses.php b/actions/twitapistatuses.php index c9943698d..ec5d378f0 100644 --- a/actions/twitapistatuses.php +++ b/actions/twitapistatuses.php @@ -136,6 +136,64 @@ class TwitapistatusesAction extends TwitterapiAction } + function group_timeline($args, $apidata) + { + parent::handle($args); + + $this->auth_user = $apidata['user']; + $group = $this->get_group($apidata['api_arg'], $apidata); + + if (empty($group)) { + $this->clientError('Not Found', 404, $apidata['content-type']); + return; + } + + $sitename = common_config('site', 'name'); + $title = sprintf(_("%s timeline"), $group->nickname); + $taguribase = common_config('integration', 'taguri'); + $id = "tag:$taguribase:GroupTimeline:".$group->id; + $link = common_local_url('showstream', + array('nickname' => $group->nickname)); + $subtitle = sprintf(_('Updates from %1$s on %2$s!'), + $group->nickname, $sitename); + + $page = (int)$this->arg('page', 1); + $count = (int)$this->arg('count', 20); + $max_id = (int)$this->arg('max_id', 0); + $since_id = (int)$this->arg('since_id', 0); + $since = $this->arg('since'); + + $notice = $group->getNotices(($page-1)*$count, + $count, $since_id, $max_id, $since); + + switch($apidata['content-type']) { + case 'xml': + $this->show_xml_timeline($notice); + break; + case 'rss': + $this->show_rss_timeline($notice, $title, $link, + $subtitle, $suplink); + break; + case 'atom': + if (isset($apidata['api_arg'])) { + $selfuri = common_root_url() . + 'api/statuses/group_timeline/' . + $apidata['api_arg'] . '.atom'; + } else { + $selfuri = common_root_url() . + 'api/statuses/group_timeline.atom'; + } + $this->show_atom_timeline($notice, $title, $id, $link, + $subtitle, $suplink, $selfuri); + break; + case 'json': + $this->show_json_timeline($notice); + break; + default: + $this->clientError(_('API method not found!'), $code = 404); + } + } + function user_timeline($args, $apidata) { parent::handle($args); diff --git a/lib/router.php b/lib/router.php index 75e72f932..bc063038f 100644 --- a/lib/router.php +++ b/lib/router.php @@ -266,7 +266,7 @@ class Router $m->connect('api/statuses/:method/:argument', array('action' => 'api', 'apiaction' => 'statuses'), - array('method' => '(user_timeline|friends_timeline|replies|mentions|show|destroy|friends|followers)')); + array('method' => '(group_timeline|user_timeline|friends_timeline|replies|mentions|show|destroy|friends|followers)')); // users diff --git a/lib/twitterapi.php b/lib/twitterapi.php index f48513e67..d2515070d 100644 --- a/lib/twitterapi.php +++ b/lib/twitterapi.php @@ -774,6 +774,34 @@ class TwitterapiAction extends Action } } + function get_group($id, $apidata=null) + { + if (empty($id)) { + + if (is_numeric($this->arg('id'))) { + return User::staticGet($this->arg('id')); + } else if ($this->arg('id')) { + $nickname = common_canonical_nickname($this->arg('id')); + return User_group::staticGet('nickname', $nickname); + } else if ($this->arg('user_id')) { + // This is to ensure that a non-numeric user_id still + // overrides screen_name even if it doesn't get used + if (is_numeric($this->arg('user_id'))) { + return User_group::staticGet('id', $this->arg('user_id')); + } + } else if ($this->arg('screen_name')) { + $nickname = common_canonical_nickname($this->arg('screen_name')); + return User::staticGet('nickname', $nickname); + } + + } else if (is_numeric($id)) { + return User_group::staticGet($id); + } else { + $nickname = common_canonical_nickname($id); + return User_group::staticGet('nickname', $nickname); + } + } + function get_profile($id) { if (is_numeric($id)) { -- cgit v1.2.3-54-g00ecf From 544a14d290cc6c08950b2d4a6faf324704e90c6c Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Fri, 10 Jul 2009 17:56:01 -0700 Subject: Move groups timeline API method into groups API action --- actions/twitapigroups.php | 114 ++++++++++++++++++++++++++++++++++++++++++++ actions/twitapistatuses.php | 58 ---------------------- lib/router.php | 7 ++- 3 files changed, 120 insertions(+), 59 deletions(-) create mode 100644 actions/twitapigroups.php (limited to 'lib') diff --git a/actions/twitapigroups.php b/actions/twitapigroups.php new file mode 100644 index 000000000..c8aae173f --- /dev/null +++ b/actions/twitapigroups.php @@ -0,0 +1,114 @@ +. + * + * @category Twitter + * @package Laconica + * @author Craig Andrews + * @author Zach Copley + * @copyright 2009 Control Yourself, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ + +if (!defined('LACONICA')) { + exit(1); +} + +require_once INSTALLDIR.'/lib/twitterapi.php'; + +/** + * Group-specific API methods + * + * This class handles Laconica group API methods. + * + * @category Twitter + * @package Laconica + * @author Craig Andrews + * @author Zach Copley + * @copyright 2009 Control Yourself, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ + + class TwitapigroupsAction extends TwitterapiAction + { + + function timeline($args, $apidata) + { + parent::handle($args); + + common_debug("in groups api action"); + + $this->auth_user = $apidata['user']; + $group = $this->get_group($apidata['api_arg'], $apidata); + + if (empty($group)) { + $this->clientError('Not Found', 404, $apidata['content-type']); + return; + } + + $sitename = common_config('site', 'name'); + $title = sprintf(_("%s timeline"), $group->nickname); + $taguribase = common_config('integration', 'taguri'); + $id = "tag:$taguribase:GroupTimeline:".$group->id; + $link = common_local_url('showstream', + array('nickname' => $group->nickname)); + $subtitle = sprintf(_('Updates from %1$s on %2$s!'), + $group->nickname, $sitename); + + $page = (int)$this->arg('page', 1); + $count = (int)$this->arg('count', 20); + $max_id = (int)$this->arg('max_id', 0); + $since_id = (int)$this->arg('since_id', 0); + $since = $this->arg('since'); + + $notice = $group->getNotices(($page-1)*$count, + $count, $since_id, $max_id, $since); + + switch($apidata['content-type']) { + case 'xml': + $this->show_xml_timeline($notice); + break; + case 'rss': + $this->show_rss_timeline($notice, $title, $link, + $subtitle, $suplink); + break; + case 'atom': + if (isset($apidata['api_arg'])) { + $selfuri = common_root_url() . + 'api/statuses/group_timeline/' . + $apidata['api_arg'] . '.atom'; + } else { + $selfuri = common_root_url() . + 'api/statuses/group_timeline.atom'; + } + $this->show_atom_timeline($notice, $title, $id, $link, + $subtitle, $suplink, $selfuri); + break; + case 'json': + $this->show_json_timeline($notice); + break; + default: + $this->clientError(_('API method not found!'), $code = 404); + } + } + +} \ No newline at end of file diff --git a/actions/twitapistatuses.php b/actions/twitapistatuses.php index ec5d378f0..c9943698d 100644 --- a/actions/twitapistatuses.php +++ b/actions/twitapistatuses.php @@ -136,64 +136,6 @@ class TwitapistatusesAction extends TwitterapiAction } - function group_timeline($args, $apidata) - { - parent::handle($args); - - $this->auth_user = $apidata['user']; - $group = $this->get_group($apidata['api_arg'], $apidata); - - if (empty($group)) { - $this->clientError('Not Found', 404, $apidata['content-type']); - return; - } - - $sitename = common_config('site', 'name'); - $title = sprintf(_("%s timeline"), $group->nickname); - $taguribase = common_config('integration', 'taguri'); - $id = "tag:$taguribase:GroupTimeline:".$group->id; - $link = common_local_url('showstream', - array('nickname' => $group->nickname)); - $subtitle = sprintf(_('Updates from %1$s on %2$s!'), - $group->nickname, $sitename); - - $page = (int)$this->arg('page', 1); - $count = (int)$this->arg('count', 20); - $max_id = (int)$this->arg('max_id', 0); - $since_id = (int)$this->arg('since_id', 0); - $since = $this->arg('since'); - - $notice = $group->getNotices(($page-1)*$count, - $count, $since_id, $max_id, $since); - - switch($apidata['content-type']) { - case 'xml': - $this->show_xml_timeline($notice); - break; - case 'rss': - $this->show_rss_timeline($notice, $title, $link, - $subtitle, $suplink); - break; - case 'atom': - if (isset($apidata['api_arg'])) { - $selfuri = common_root_url() . - 'api/statuses/group_timeline/' . - $apidata['api_arg'] . '.atom'; - } else { - $selfuri = common_root_url() . - 'api/statuses/group_timeline.atom'; - } - $this->show_atom_timeline($notice, $title, $id, $link, - $subtitle, $suplink, $selfuri); - break; - case 'json': - $this->show_json_timeline($notice); - break; - default: - $this->clientError(_('API method not found!'), $code = 404); - } - } - function user_timeline($args, $apidata) { parent::handle($args); diff --git a/lib/router.php b/lib/router.php index bc063038f..cd2143d13 100644 --- a/lib/router.php +++ b/lib/router.php @@ -266,7 +266,7 @@ class Router $m->connect('api/statuses/:method/:argument', array('action' => 'api', 'apiaction' => 'statuses'), - array('method' => '(group_timeline|user_timeline|friends_timeline|replies|mentions|show|destroy|friends|followers)')); + array('method' => '(|user_timeline|friends_timeline|replies|mentions|show|destroy|friends|followers)')); // users @@ -394,6 +394,11 @@ class Router array('action' => 'api', 'apiaction' => 'laconica')); + // Groups + $m->connect('api/laconica/groups/:method/:argument', + array('action' => 'api', + 'apiaction' => 'groups')); + // search $m->connect('api/search.atom', array('action' => 'twitapisearchatom')); $m->connect('api/search.json', array('action' => 'twitapisearchjson')); -- cgit v1.2.3-54-g00ecf From 0ac08c1fb3a930af420cb9c4252bc6f499ba1141 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Fri, 10 Jul 2009 18:22:19 -0700 Subject: Make get_group() behave more like get_user() --- lib/router.php | 4 ++++ lib/twitterapi.php | 14 +++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) (limited to 'lib') diff --git a/lib/router.php b/lib/router.php index cd2143d13..8104d7818 100644 --- a/lib/router.php +++ b/lib/router.php @@ -399,6 +399,10 @@ class Router array('action' => 'api', 'apiaction' => 'groups')); + $m->connect('api/laconica/groups/:method', + array('action' => 'api', + 'apiaction' => 'groups')); + // search $m->connect('api/search.atom', array('action' => 'twitapisearchatom')); $m->connect('api/search.json', array('action' => 'twitapisearchjson')); diff --git a/lib/twitterapi.php b/lib/twitterapi.php index d2515070d..4f3a5c0b6 100644 --- a/lib/twitterapi.php +++ b/lib/twitterapi.php @@ -779,19 +779,19 @@ class TwitterapiAction extends Action if (empty($id)) { if (is_numeric($this->arg('id'))) { - return User::staticGet($this->arg('id')); + return User_group::staticGet($this->arg('id')); } else if ($this->arg('id')) { $nickname = common_canonical_nickname($this->arg('id')); return User_group::staticGet('nickname', $nickname); - } else if ($this->arg('user_id')) { + } else if ($this->arg('group_id')) { // This is to ensure that a non-numeric user_id still // overrides screen_name even if it doesn't get used - if (is_numeric($this->arg('user_id'))) { - return User_group::staticGet('id', $this->arg('user_id')); + if (is_numeric($this->arg('group_id'))) { + return User_group::staticGet('id', $this->arg('group_id')); } - } else if ($this->arg('screen_name')) { - $nickname = common_canonical_nickname($this->arg('screen_name')); - return User::staticGet('nickname', $nickname); + } else if ($this->arg('group_name')) { + $nickname = common_canonical_nickname($this->arg('group_name')); + return User_group::staticGet('nickname', $nickname); } } else if (is_numeric($id)) { -- cgit v1.2.3-54-g00ecf From 91324890ae130a6f4280c9f6d82151793611de1f Mon Sep 17 00:00:00 2001 From: Craig Andrews Date: Sun, 12 Jul 2009 15:07:54 -0400 Subject: Add timeline tags API (RSS 2.0 and Atom feeds) --- actions/api.php | 1 + actions/tag.php | 20 ++++++++- actions/twitapitags.php | 114 ++++++++++++++++++++++++++++++++++++++++++++++++ lib/router.php | 9 ++++ 4 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 actions/twitapitags.php (limited to 'lib') diff --git a/actions/api.php b/actions/api.php index 4a00b77e8..452ed8e82 100644 --- a/actions/api.php +++ b/actions/api.php @@ -128,6 +128,7 @@ class ApiAction extends Action 'laconica/version', 'laconica/config', 'laconica/wadl', + 'tags/timeline', 'groups/timeline'); static $bareauth = array('statuses/user_timeline', diff --git a/actions/tag.php b/actions/tag.php index 888aba062..020399d9e 100644 --- a/actions/tag.php +++ b/actions/tag.php @@ -72,8 +72,24 @@ class TagAction extends Action function getFeeds() { return array(new Feed(Feed::RSS1, - common_local_url('tagrss', array('tag' => $this->tag)), - sprintf(_('Feed for tag %s'), $this->tag))); + common_local_url('tagrss', + array('tag' => $this->tag)), + sprintf(_('Notice feed for tag %s (RSS 1.0)'), + $this->tag)), + new Feed(Feed::RSS2, + common_local_url('api', + array('apiaction' => 'tags', + 'method' => 'timeline', + 'argument' => $this->tag.'.rss')), + sprintf(_('Notice feed for %s group (RSS 2.0)'), + $this->tag)), + new Feed(Feed::ATOM, + common_local_url('api', + array('apiaction' => 'tags', + 'method' => 'timeline', + 'argument' => $this->tag.'.atom')), + sprintf(_('Notice feed for tag %s (Atom)'), + $this->tag))); } function showContent() diff --git a/actions/twitapitags.php b/actions/twitapitags.php new file mode 100644 index 000000000..5c8527530 --- /dev/null +++ b/actions/twitapitags.php @@ -0,0 +1,114 @@ +. + * + * @category Twitter + * @package Laconica + * @author Craig Andrews + * @author Zach Copley + * @copyright 2009 Control Yourself, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ + +if (!defined('LACONICA')) { + exit(1); +} + +require_once INSTALLDIR.'/lib/twitterapi.php'; + +/** + * Group-specific API methods + * + * This class handles Laconica group API methods. + * + * @category Twitter + * @package Laconica + * @author Craig Andrews + * @author Zach Copley + * @copyright 2009 Control Yourself, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ + + class TwitapitagsAction extends TwitterapiAction + { + + function timeline($args, $apidata) + { + parent::handle($args); + + common_debug("in tags api action"); + + $this->auth_user = $apidata['user']; + $tag = $apidata['api_arg']; + + if (empty($tag)) { + $this->clientError('Not Found', 404, $apidata['content-type']); + return; + } + + $sitename = common_config('site', 'name'); + $title = sprintf(_("Notices tagged with %s"), $tag); + $taguribase = common_config('integration', 'taguri'); + $id = "tag:$taguribase:TagTimeline:".$tag; + $link = common_local_url('tag', + array('tag' => $tag)); + $subtitle = sprintf(_('Updates tagged with %1$s on %2$s!'), + $tag, $sitename); + + $page = (int)$this->arg('page', 1); + $count = (int)$this->arg('count', 20); + $max_id = (int)$this->arg('max_id', 0); + $since_id = (int)$this->arg('since_id', 0); + $since = $this->arg('since'); + + # XXX: support max_id, since_id, and since arguments + $notice = Notice_tag::getStream($tag, ($page-1)*$count, $count + 1); + + switch($apidata['content-type']) { + case 'xml': + $this->show_xml_timeline($notice); + break; + case 'rss': + $this->show_rss_timeline($notice, $title, $link, + $subtitle, $suplink); + break; + case 'atom': + if (isset($apidata['api_arg'])) { + $selfuri = common_root_url() . + 'api/laconica/tags/timeline/' . + $apidata['api_arg'] . '.atom'; + } else { + $selfuri = common_root_url() . + 'api/laconica/tags/timeline.atom'; + } + $this->show_atom_timeline($notice, $title, $id, $link, + $subtitle, $suplink, $selfuri); + break; + case 'json': + $this->show_json_timeline($notice); + break; + default: + $this->clientError(_('API method not found!'), $code = 404); + } + } + +} diff --git a/lib/router.php b/lib/router.php index 8104d7818..e12138637 100644 --- a/lib/router.php +++ b/lib/router.php @@ -403,6 +403,15 @@ class Router array('action' => 'api', 'apiaction' => 'groups')); + // Tags + $m->connect('api/laconica/tags/:method/:argument', + array('action' => 'api', + 'apiaction' => 'tags')); + + $m->connect('api/laconica/tags/:method', + array('action' => 'api', + 'apiaction' => 'tags')); + // search $m->connect('api/search.atom', array('action' => 'twitapisearchatom')); $m->connect('api/search.json', array('action' => 'twitapisearchjson')); -- cgit v1.2.3-54-g00ecf From a68773df63aa925d860d555d621d5180798f83db Mon Sep 17 00:00:00 2001 From: Toby Inkster Date: Mon, 13 Jul 2009 15:16:10 +0100 Subject: Improve output for files/attachments. --- lib/rssaction.php | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/rssaction.php b/lib/rssaction.php index fe3fd6f4a..abc83fe3a 100644 --- a/lib/rssaction.php +++ b/lib/rssaction.php @@ -219,7 +219,30 @@ class Rss10Action extends Action $attachments = $notice->attachments(); if($attachments){ foreach($attachments as $attachment){ - $this->element('enc:enclosure', array('rdf:resource'=>$attachment->url,'enc:type'=>$attachment->mimetype,'enc:length'=>$attachment->size), null); + if (isset($attachment->filename)) { + // DO NOT move xmlns declaration to root element. Making it + // the default namespace here improves compatibility with + // real-world feed readers. + $attribs = array( + 'rdf:resource' => $attachment->url, + 'url' => $attachment->url, + 'xmlns' => 'http://purl.oclc.org/net/rss_2.0/enc#' + ); + if ($attachment->title) { + $attribs['dc:title'] = $attachment->title; + } + if ($attachment->modified) { + $attribs['dc:date'] = common_date_w3dtf($attachment->modified); + } + if ($attachment->size) { + $attribs['length'] = $attachment->size; + } + if ($attachment->mimetype) { + $attribs['type'] = $attachment->mimetype; + } + $this->element('enclosure', $attribs); + } + $this->element('sioc:links_to', array('rdf:resource'=>$attachment->url)); } } @@ -258,8 +281,6 @@ class Rss10Action extends Action 'http://creativecommons.org/ns#', 'xmlns:content' => 'http://purl.org/rss/1.0/modules/content/', - 'xmlns:enc' => - 'http://purl.oclc.org/net/rss_2.0/enc#', 'xmlns:foaf' => 'http://xmlns.com/foaf/0.1/', 'xmlns:sioc' => -- cgit v1.2.3-54-g00ecf From ae2bc6a8500f2878ed376f60c81c3c53c8ab5b87 Mon Sep 17 00:00:00 2001 From: Toby Inkster Date: Mon, 13 Jul 2009 15:37:15 +0100 Subject: Add notice tags to RSS 1.0 output. --- lib/rssaction.php | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/rssaction.php b/lib/rssaction.php index abc83fe3a..183c09f47 100644 --- a/lib/rssaction.php +++ b/lib/rssaction.php @@ -192,6 +192,24 @@ class Rss10Action extends Action } } + // XXX: Surely there should be a common function to do this? + function extract_tags ($string) + { + $count = preg_match_all('/(?:^|\s)#([A-Za-z0-9_\-\.]{1,64})/', strtolower($string), $match); + if (!count) + { + return array(); + } + + $rv = array(); + foreach ($match[1] as $tag) + { + $rv[] = common_canonical_tag($tag); + } + + return array_unique($rv); + } + function showItem($notice) { $profile = Profile::staticGet($notice->profile_id); @@ -245,7 +263,20 @@ class Rss10Action extends Action $this->element('sioc:links_to', array('rdf:resource'=>$attachment->url)); } } - + $tags = $this->extract_tags($notice->content); + if (!empty($tags)) { + foreach ($tags as $tag) + { + $tagpage = common_local_url('tag', array('tag' => $tag)); + $tagrss = common_local_url('tagrss', array('tag' => $tag)); + $this->elementStart('ctag:tagged'); + $this->elementStart('ctag:Tag', array('rdf:about'=>$tagpage.'#concept', 'ctag:label'=>$tag)); + $this->element('foaf:page', array('rdf:resource'=>$tagpage)); + $this->element('rdfs:seeAlso', array('rdf:resource'=>$tagrss)); + $this->elementEnd('ctag:Tag'); + $this->elementEnd('ctag:tagged'); + } + } $this->elementEnd('item'); $this->creators[$creator_uri] = $profile; } @@ -281,6 +312,8 @@ class Rss10Action extends Action 'http://creativecommons.org/ns#', 'xmlns:content' => 'http://purl.org/rss/1.0/modules/content/', + 'xmlns:ctag' => + 'http://commontag.org/ns#', 'xmlns:foaf' => 'http://xmlns.com/foaf/0.1/', 'xmlns:sioc' => -- cgit v1.2.3-54-g00ecf From 38784141d108a96cc173167e16a1c79d9098722a Mon Sep 17 00:00:00 2001 From: Toby Inkster Date: Mon, 13 Jul 2009 16:56:52 +0100 Subject: Copy isset($attachment->filename) fix from RSS 1.0 to RSS 2.0 and Atom 1.0 feeds. --- classes/Notice.php | 10 ++++++---- lib/twitterapi.php | 12 +++++++----- 2 files changed, 13 insertions(+), 9 deletions(-) (limited to 'lib') diff --git a/classes/Notice.php b/classes/Notice.php index 75044cf63..fc28f3558 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -1170,11 +1170,13 @@ class Notice extends Memcached_DataObject $attachments = $this->attachments(); if($attachments){ foreach($attachments as $attachment){ - $attributes = array('rel'=>'enclosure','href'=>$attachment->url,'type'=>$attachment->mimetype,'length'=>$attachment->size); - if($attachment->title){ - $attributes['title']=$attachment->title; + if (isset($attachment->filename)) { + $attributes = array('rel'=>'enclosure','href'=>$attachment->url,'type'=>$attachment->mimetype,'length'=>$attachment->size); + if($attachment->title){ + $attributes['title']=$attachment->title; + } + $xs->element('link', $attributes, null); } - $xs->element('link', $attributes, null); } } diff --git a/lib/twitterapi.php b/lib/twitterapi.php index 4f3a5c0b6..ce188e00d 100644 --- a/lib/twitterapi.php +++ b/lib/twitterapi.php @@ -218,11 +218,13 @@ class TwitterapiAction extends Action if($attachments){ $entry['enclosures']=array(); foreach($attachments as $attachment){ - $enclosure=array(); - $enclosure['url']=$attachment->url; - $enclosure['mimetype']=$attachment->mimetype; - $enclosure['size']=$attachment->size; - $entry['enclosures'][]=$enclosure; + if (isset($attachment->filename)) { + $enclosure=array(); + $enclosure['url']=$attachment->url; + $enclosure['mimetype']=$attachment->mimetype; + $enclosure['size']=$attachment->size; + $entry['enclosures'][]=$enclosure; + } } } -- cgit v1.2.3-54-g00ecf From 593af9feb6cdbb88e250501938722e656fe4a17a Mon Sep 17 00:00:00 2001 From: Craig Andrews Date: Tue, 14 Jul 2009 13:33:40 -0400 Subject: Moved the decision logic as to whether an attachment should be an enclosure to the File class --- classes/File.php | 13 +++++++++++++ classes/Notice.php | 2 +- lib/rssaction.php | 2 +- lib/twitterapi.php | 2 +- 4 files changed, 16 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/classes/File.php b/classes/File.php index 533cc6e71..289c6e441 100644 --- a/classes/File.php +++ b/classes/File.php @@ -193,5 +193,18 @@ class File extends Memcached_DataObject return 'http://'.$server.$path.$filename; } + + function isEnclosure(){ + if(isset($this->filename)){ + return true; + } + $notEnclosureMimeTypes = array('text/html'); + $mimetype = strtolower($this->mimetype); + $semicolon = strpos($mimetype,';'); + if($semicolon){ + $mimetype = substr($mimetype,0,$semicolon); + } + return(! in_array($mimetype,$notEnclosureMimeTypes)); + } } diff --git a/classes/Notice.php b/classes/Notice.php index fc28f3558..08125cf7b 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -1170,7 +1170,7 @@ class Notice extends Memcached_DataObject $attachments = $this->attachments(); if($attachments){ foreach($attachments as $attachment){ - if (isset($attachment->filename)) { + if ($attachment->isEnclosure()) { $attributes = array('rel'=>'enclosure','href'=>$attachment->url,'type'=>$attachment->mimetype,'length'=>$attachment->size); if($attachment->title){ $attributes['title']=$attachment->title; diff --git a/lib/rssaction.php b/lib/rssaction.php index 183c09f47..ffa1f9e99 100644 --- a/lib/rssaction.php +++ b/lib/rssaction.php @@ -237,7 +237,7 @@ class Rss10Action extends Action $attachments = $notice->attachments(); if($attachments){ foreach($attachments as $attachment){ - if (isset($attachment->filename)) { + if ($attachment->isEnclosure()) { // DO NOT move xmlns declaration to root element. Making it // the default namespace here improves compatibility with // real-world feed readers. diff --git a/lib/twitterapi.php b/lib/twitterapi.php index ce188e00d..655b6c777 100644 --- a/lib/twitterapi.php +++ b/lib/twitterapi.php @@ -218,7 +218,7 @@ class TwitterapiAction extends Action if($attachments){ $entry['enclosures']=array(); foreach($attachments as $attachment){ - if (isset($attachment->filename)) { + if ($attachment->isEnclosure()) { $enclosure=array(); $enclosure['url']=$attachment->url; $enclosure['mimetype']=$attachment->mimetype; -- cgit v1.2.3-54-g00ecf From 75545cdc07db0e12a351ed0f519675626dd2e7bd Mon Sep 17 00:00:00 2001 From: Craig Andrews Date: Wed, 15 Jul 2009 10:37:50 -0400 Subject: Added attachment information to the json responses --- lib/twitterapi.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'lib') diff --git a/lib/twitterapi.php b/lib/twitterapi.php index 655b6c777..749083c7c 100644 --- a/lib/twitterapi.php +++ b/lib/twitterapi.php @@ -186,6 +186,21 @@ class TwitterapiAction extends Action $twitter_status['favorited'] = false; } + # Enclosures + $attachments = $notice->attachments(); + $twitter_status['attachments']=array(); + if($attachments){ + foreach($attachments as $attachment){ + if ($attachment->isEnclosure()) { + $enclosure=array(); + $enclosure['url']=$attachment->url; + $enclosure['mimetype']=$attachment->mimetype; + $enclosure['size']=$attachment->size; + $twitter_status['attachments'][]=$enclosure; + } + } + } + if ($include_user) { # Don't get notice (recursive!) $twitter_user = $this->twitter_user_array($profile, false); -- cgit v1.2.3-54-g00ecf From c07c4b20502735104cc35d260b4c7f3904a3a9fb Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Wed, 15 Jul 2009 23:36:08 -0400 Subject: change version to 0.8.1dev --- lib/common.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/common.php b/lib/common.php index c47702779..9d7954fa9 100644 --- a/lib/common.php +++ b/lib/common.php @@ -19,7 +19,7 @@ if (!defined('LACONICA')) { exit(1); } -define('LACONICA_VERSION', '0.8.0'); +define('LACONICA_VERSION', '0.8.1dev'); define('AVATAR_PROFILE_SIZE', 96); define('AVATAR_STREAM_SIZE', 48); -- cgit v1.2.3-54-g00ecf From 7cfb2f569dbda8ef84149604cec88b2349d95306 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Thu, 9 Jul 2009 18:22:46 -0400 Subject: 0.9.0 dev version --- lib/common.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/common.php b/lib/common.php index 9d7954fa9..764c5a077 100644 --- a/lib/common.php +++ b/lib/common.php @@ -19,7 +19,7 @@ if (!defined('LACONICA')) { exit(1); } -define('LACONICA_VERSION', '0.8.1dev'); +define('LACONICA_VERSION', '0.9.0dev'); define('AVATAR_PROFILE_SIZE', 96); define('AVATAR_STREAM_SIZE', 48); -- cgit v1.2.3-54-g00ecf