diff options
Diffstat (limited to 'actions/twitapistatuses.php')
-rw-r--r-- | actions/twitapistatuses.php | 399 |
1 files changed, 171 insertions, 228 deletions
diff --git a/actions/twitapistatuses.php b/actions/twitapistatuses.php index 1fbde6639..94f624afb 100644 --- a/actions/twitapistatuses.php +++ b/actions/twitapistatuses.php @@ -17,7 +17,9 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -if (!defined('LACONICA')) { exit(1); } +if (!defined('LACONICA')) { + exit(1); +} require_once(INSTALLDIR.'/lib/twitterapi.php'); @@ -26,64 +28,45 @@ class TwitapistatusesAction extends TwitterapiAction function public_timeline($args, $apidata) { - parent::handle($args); - - $sitename = common_config('site', 'name'); - $title = sprintf(_("%s public timeline"), $sitename); - - $taguribase = common_config('integration', 'taguri'); - $id = "tag:$taguribase:PublicTimeline"; - $link = common_root_url(); - - $subtitle = sprintf(_("%s updates from everyone!"), $sitename); - - // Number of public statuses to return by default -- Twitter sends 20 - $MAX_PUBSTATUSES = 20; - - // FIXME: To really live up to the spec we need to build a list + // XXX: To really live up to the spec we need to build a list // of notices by users who have custom avatars, so fix this SQL -- Zach - $page = $this->arg('page'); - $since_id = $this->arg('since_id'); - $max_id = $this->arg('max_id'); - - if (!$page) { - $page = 1; - } - if (!$since_id) { - $since_id = 0; - } - if (!$max_id) { - $max_id = 0; - } + parent::handle($args); - $since = strtotime($this->arg('since')); + $sitename = common_config('site', 'name'); + $title = sprintf(_("%s public timeline"), $sitename); + $taguribase = common_config('integration', 'taguri'); + $id = "tag:$taguribase:PublicTimeline"; + $link = common_root_url(); + $subtitle = sprintf(_("%s updates from everyone!"), $sitename); - $notice = Notice::publicStream((($page-1)*$MAX_PUBSTATUSES), $MAX_PUBSTATUSES, $since_id, $max_id, $since); + $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'); - if ($notice) { + $notice = Notice::publicStream(($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); - break; - case 'atom': - $selfuri = common_root_url() . 'api/statuses/public_timeline.atom'; - $this->show_atom_timeline($notice, $title, $id, $link, $subtitle, null, $selfuri); - break; - case 'json': - $this->show_json_timeline($notice); - break; - default: - $this->clientError(_('API method not found!'), $code = 404); - break; - } - - } else { - $this->serverError(_('Couldn\'t find any statuses.'), $code = 503); + switch($apidata['content-type']) { + case 'xml': + $this->show_xml_timeline($notice); + break; + case 'rss': + $this->show_rss_timeline($notice, $title, $link, $subtitle); + break; + case 'atom': + $selfuri = common_root_url() . 'api/statuses/public_timeline.atom'; + $this->show_atom_timeline($notice, $title, $id, $link, + $subtitle, null, $selfuri); + break; + case 'json': + $this->show_json_timeline($notice); + break; + default: + $this->clientError(_('API method not found!'), $code = 404); + break; } } @@ -92,68 +75,57 @@ class TwitapistatusesAction extends TwitterapiAction { parent::handle($args); - $since = $this->arg('since'); - $since_id = $this->arg('since_id'); - $count = $this->arg('count'); - $page = $this->arg('page'); - $max_id = $this->arg('max_id'); - - if (!$page) { - $page = 1; - } - - if (!$count) { - $count = 20; - } - - if (!$since_id) { - $since_id = 0; - } - - if (!$max_id) { - $max_id = 0; - } - - $since = strtotime($this->arg('since')); $user = $this->get_user($apidata['api_arg'], $apidata); $this->auth_user = $user; if (empty($user)) { - $this->clientError(_('No such user!'), 404, $apidata['content-type']); + $this->clientError(_('No such user!'), 404, + $apidata['content-type']); return; } - $profile = $user->getProfile(); - $sitename = common_config('site', 'name'); - $title = sprintf(_("%s and friends"), $user->nickname); + $profile = $user->getProfile(); + $sitename = common_config('site', 'name'); + $title = sprintf(_("%s and friends"), $user->nickname); $taguribase = common_config('integration', 'taguri'); - $id = "tag:$taguribase:FriendsTimeline:" . $user->id; - $link = common_local_url('all', array('nickname' => $user->nickname)); - $subtitle = sprintf(_('Updates from %1$s and friends on %2$s!'), $user->nickname, $sitename); + $id = "tag:$taguribase:FriendsTimeline:" . $user->id; + $link = common_local_url('all', + array('nickname' => $user->nickname)); + $subtitle = sprintf(_('Updates from %1$s and friends on %2$s!'), + $user->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 = $user->noticesWithFriends(($page-1)*20, $count, $since_id, $max_id, $since); + $notice = $user->noticesWithFriends(($page-1)*$count, + $count, $since_id, $max_id,$since); switch($apidata['content-type']) { - case 'xml': + case 'xml': $this->show_xml_timeline($notice); break; - case 'rss': + case 'rss': $this->show_rss_timeline($notice, $title, $link, $subtitle); break; - case 'atom': + case 'atom': if (isset($apidata['api_arg'])) { $selfuri = common_root_url() . - 'api/statuses/friends_timeline/' . $apidata['api_arg'] . '.atom'; + 'api/statuses/friends_timeline/' . + $apidata['api_arg'] . '.atom'; } else { $selfuri = common_root_url() . 'api/statuses/friends_timeline.atom'; } - $this->show_atom_timeline($notice, $title, $id, $link, $subtitle, null, $selfuri); + $this->show_atom_timeline($notice, $title, $id, $link, + $subtitle, null, $selfuri); break; - case 'json': + case 'json': $this->show_json_timeline($notice); break; - default: + default: $this->clientError(_('API method not found!'), $code = 404); } @@ -166,48 +138,21 @@ class TwitapistatusesAction extends TwitterapiAction $this->auth_user = $apidata['user']; $user = $this->get_user($apidata['api_arg'], $apidata); - if (!$user) { + if (empty($user)) { $this->clientError('Not Found', 404, $apidata['content-type']); return; } $profile = $user->getProfile(); - if (!$profile) { - $this->serverError(_('User has no profile.')); - return; - } - - $count = $this->arg('count'); - $since = $this->arg('since'); - $since_id = $this->arg('since_id'); - $page = $this->arg('page'); - $max_id = $this->arg('max_id'); - - if (!$page) { - $page = 1; - } - - if (!$count) { - $count = 20; - } - - if (!$since_id) { - $since_id = 0; - } - - if (!$max_id) { - $max_id = 0; - } - - $since = strtotime($this->arg('since')); - - $sitename = common_config('site', 'name'); - $title = sprintf(_("%s timeline"), $user->nickname); + $sitename = common_config('site', 'name'); + $title = sprintf(_("%s timeline"), $user->nickname); $taguribase = common_config('integration', 'taguri'); - $id = "tag:$taguribase:UserTimeline:".$user->id; - $link = common_local_url('showstream', array('nickname' => $user->nickname)); - $subtitle = sprintf(_('Updates from %1$s on %2$s!'), $user->nickname, $sitename); + $id = "tag:$taguribase:UserTimeline:".$user->id; + $link = common_local_url('showstream', + array('nickname' => $user->nickname)); + $subtitle = sprintf(_('Updates from %1$s on %2$s!'), + $user->nickname, $sitename); # FriendFeed's SUP protocol # Also added RSS and Atom feeds @@ -215,26 +160,34 @@ class TwitapistatusesAction extends TwitterapiAction $suplink = common_local_url('sup', null, null, $user->id); header('X-SUP-ID: '.$suplink); - # XXX: since + $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 = $user->getNotices((($page-1)*20), $count, $since_id, $max_id, $since); + $notice = $user->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); + $this->show_rss_timeline($notice, $title, $link, + $subtitle, $suplink); break; case 'atom': if (isset($apidata['api_arg'])) { $selfuri = common_root_url() . - 'api/statuses/user_timeline/' . $apidata['api_arg'] . '.atom'; + 'api/statuses/user_timeline/' . + $apidata['api_arg'] . '.atom'; } else { $selfuri = common_root_url() . 'api/statuses/user_timeline.atom'; } - $this->show_atom_timeline($notice, $title, $id, $link, $subtitle, $suplink, $selfuri); + $this->show_atom_timeline($notice, $title, $id, $link, + $subtitle, $suplink, $selfuri); break; case 'json': $this->show_json_timeline($notice); @@ -247,7 +200,6 @@ class TwitapistatusesAction extends TwitterapiAction function update($args, $apidata) { - parent::handle($args); if (!in_array($apidata['content-type'], array('xml', 'json'))) { @@ -256,21 +208,24 @@ class TwitapistatusesAction extends TwitterapiAction } if ($_SERVER['REQUEST_METHOD'] != 'POST') { - $this->clientError(_('This method requires a POST.'), 400, $apidata['content-type']); + $this->clientError(_('This method requires a POST.'), + 400, $apidata['content-type']); return; } - $this->auth_user = $apidata['user']; - $user = $this->auth_user; + $user = $apidata['user']; // Always the auth user + $status = $this->trimmed('status'); $source = $this->trimmed('source'); - $in_reply_to_status_id = intval($this->trimmed('in_reply_to_status_id')); + $in_reply_to_status_id = + intval($this->trimmed('in_reply_to_status_id')); $reserved_sources = array('web', 'omb', 'mail', 'xmpp', 'api'); - if (!$source || in_array($source, $reserved_sources)) { + + if (empty($source) || in_array($source, $reserved_sources)) { $source = 'api'; } - if (!$status) { + if (empty($status)) { // XXX: Note: In this case, Twitter simply returns '200 OK' // No error is given, but the status is not posted to the @@ -288,9 +243,9 @@ class TwitapistatusesAction extends TwitterapiAction // as "truncated." Sending this error may screw up some clients // that assume Twitter will truncate for them. Should we just // truncate too? -- Zach - $this->clientError(_('That\'s too long. Max notice size is 140 chars.'), $code = 406, $apidata['content-type']); + $this->clientError(_('That\'s too long. Max notice size is 140 chars.'), + $code = 406, $apidata['content-type']); return; - } } @@ -321,13 +276,15 @@ class TwitapistatusesAction extends TwitterapiAction if ($reply) { $reply_to = $in_reply_to_status_id; } else { - $this->clientError(_('Not found'), $code = 404, $apidata['content-type']); + $this->clientError(_('Not found'), $code = 404, + $apidata['content-type']); return; } } - $notice = Notice::saveNew($user->id, html_entity_decode($status, ENT_NOQUOTES, 'UTF-8'), - $source, 1, $reply_to); + $notice = Notice::saveNew($user->id, + html_entity_decode($status, ENT_NOQUOTES, 'UTF-8'), + $source, 1, $reply_to); if (is_string($notice)) { $this->serverError($notice); @@ -343,71 +300,55 @@ class TwitapistatusesAction extends TwitterapiAction function mentions($args, $apidata) { - parent::handle($args); - $since = $this->arg('since'); - $count = $this->arg('count'); - $page = $this->arg('page'); - $since_id = $this->arg('since_id'); - $max_id = $this->arg('max_id'); - $user = $this->get_user($apidata['api_arg'], $apidata); $this->auth_user = $apidata['user']; + + if (empty($user)) { + $this->clientError(_('No such user!'), 404, + $apidata['content-type']); + return; + } + $profile = $user->getProfile(); - $sitename = common_config('site', 'name'); - $title = sprintf(_('%1$s / Updates mentioning %2$s'), + $sitename = common_config('site', 'name'); + $title = sprintf(_('%1$s / Updates mentioning %2$s'), $sitename, $user->nickname); $taguribase = common_config('integration', 'taguri'); - $id = "tag:$taguribase:Mentions:".$user->id; - $link = common_local_url('replies', array('nickname' => $user->nickname)); - $subtitle = sprintf(_('%1$s updates that reply to updates from %2$s / %3$s.'), + $id = "tag:$taguribase:Mentions:".$user->id; + $link = common_local_url('replies', + array('nickname' => $user->nickname)); + $subtitle = sprintf(_('%1$s updates that reply to updates from %2$s / %3$s.'), $sitename, $user->nickname, $profile->getBestName()); - if (!$page) { - $page = 1; - } + $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'); - if (!$count) { - $count = 20; - } - - if (!$since_id) { - $since_id = 0; - } - - if (!$max_id) { - $max_id = 0; - } - - $since = strtotime($this->arg('since')); - - $notice = $user->getReplies((($page-1)*20), + $notice = $user->getReplies(($page-1)*$count, $count, $since_id, $max_id, $since); - $notices = array(); - - while ($notice->fetch()) { - $notices[] = clone($notice); - } switch($apidata['content-type']) { - case 'xml': - $this->show_xml_timeline($notices); + case 'xml': + $this->show_xml_timeline($notice); break; - case 'rss': - $this->show_rss_timeline($notices, $title, $link, $subtitle); + case 'rss': + $this->show_rss_timeline($notice, $title, $link, $subtitle); break; - case 'atom': + case 'atom': $selfuri = common_root_url() . ltrim($_SERVER['QUERY_STRING'], 'p='); - $this->show_atom_timeline($notices, $title, $id, $link, $subtitle, + $this->show_atom_timeline($notice, $title, $id, $link, $subtitle, null, $selfuri); break; - case 'json': - $this->show_json_timeline($notices); + case 'json': + $this->show_json_timeline($notice); break; - default: + default: $this->clientError(_('API method not found!'), $code = 404); } @@ -428,8 +369,8 @@ class TwitapistatusesAction extends TwitterapiAction } $this->auth_user = $apidata['user']; - $notice_id = $apidata['api_arg']; - $notice = Notice::staticGet($notice_id); + $notice_id = $apidata['api_arg']; + $notice = Notice::staticGet($notice_id); if ($notice) { if ($apidata['content-type'] == 'xml') { @@ -438,15 +379,16 @@ class TwitapistatusesAction extends TwitterapiAction $this->show_single_json_status($notice); } } else { - // XXX: Twitter just sets a 404 header and doens't bother to return an err msg - $this->clientError(_('No status with that ID found.'), 404, $apidata['content-type']); + // XXX: Twitter just sets a 404 header and doens't bother + // to return an err msg + $this->clientError(_('No status with that ID found.'), + 404, $apidata['content-type']); } } function destroy($args, $apidata) { - parent::handle($args); if (!in_array($apidata['content-type'], array('xml', 'json'))) { @@ -457,17 +399,18 @@ class TwitapistatusesAction extends TwitterapiAction // Check for RESTfulness if (!in_array($_SERVER['REQUEST_METHOD'], array('POST', 'DELETE'))) { // XXX: Twitter just prints the err msg, no XML / JSON. - $this->clientError(_('This method requires a POST or DELETE.'), 400, $apidata['content-type']); + $this->clientError(_('This method requires a POST or DELETE.'), + 400, $apidata['content-type']); return; } - $this->auth_user = $apidata['user']; - $user = $this->auth_user; + $user = $apidata['user']; // Always the auth user $notice_id = $apidata['api_arg']; - $notice = Notice::staticGet($notice_id); + $notice = Notice::staticGet($notice_id); - if (!$notice) { - $this->clientError(_('No status found with that ID.'), 404, $apidata['content-type']); + if (empty($notice)) { + $this->clientError(_('No status found with that ID.'), + 404, $apidata['content-type']); return; } @@ -483,7 +426,8 @@ class TwitapistatusesAction extends TwitterapiAction $this->show_single_json_status($notice); } } else { - $this->clientError(_('You may not delete another user\'s status.'), 403, $apidata['content-type']); + $this->clientError(_('You may not delete another user\'s status.'), + 403, $apidata['content-type']); } } @@ -514,42 +458,41 @@ class TwitapistatusesAction extends TwitterapiAction function subscriptions($apidata, $other_attr, $user_attr, $onlyIDs=false) { - $this->auth_user = $apidata['user']; $user = $this->get_user($apidata['api_arg'], $apidata); - if (!$user) { + if (empty($user)) { $this->clientError('Not Found', 404, $apidata['content-type']); return; } - $page = $this->trimmed('page'); - - if (!$page || !is_numeric($page)) { - $page = 1; - } - $profile = $user->getProfile(); - if (!$profile) { - $this->serverError(_('User has no profile.')); - return; - } - $sub = new Subscription(); $sub->$user_attr = $profile->id; - $since = strtotime($this->trimmed('since')); - - if ($since) { - $d = date('Y-m-d H:i:s', $since); - $sub->whereAdd("created > '$d'"); - } - $sub->orderBy('created DESC'); + // Normally, page 100 friends at a time + if (!$onlyIDs) { - $sub->limit(($page-1)*100, 100); + $page = $this->arg('page', 1); + $count = $this->arg('count', 100); + $sub->limit(($page-1)*$count, $count); + } else { + + // If we're just looking at IDs, return + // ALL of them, unless the user specifies a page, + // in which case, return 500 per page. + + $page = $this->arg('page'); + if (!empty($page)) { + if ($page < 1) { + $page = 1; + } + $count = 500; + $sub->limit(($page-1)*$count, $count); + } } $others = array(); @@ -578,21 +521,21 @@ class TwitapistatusesAction extends TwitterapiAction function show_profiles($profiles, $type) { switch ($type) { - case 'xml': + case 'xml': $this->elementStart('users', array('type' => 'array')); foreach ($profiles as $profile) { $this->show_profile($profile); } $this->elementEnd('users'); break; - case 'json': + case 'json': $arrays = array(); foreach ($profiles as $profile) { $arrays[] = $this->twitter_user_array($profile, true); } print json_encode($arrays); break; - default: + default: $this->clientError(_('unsupported file type')); } } @@ -600,21 +543,21 @@ class TwitapistatusesAction extends TwitterapiAction function showIDs($profiles, $type) { switch ($type) { - case 'xml': + case 'xml': $this->elementStart('ids'); foreach ($profiles as $profile) { $this->element('id', null, $profile->id); } $this->elementEnd('ids'); break; - case 'json': + case 'json': $ids = array(); foreach ($profiles as $profile) { $ids[] = (int)$profile->id; } print json_encode($ids); break; - default: + default: $this->clientError(_('unsupported file type')); } } @@ -627,8 +570,8 @@ class TwitapistatusesAction extends TwitterapiAction function supported($cmd) { - - $cmdlist = array('MessageCommand', 'SubCommand', 'UnsubCommand', 'FavCommand', 'OnCommand', 'OffCommand'); + $cmdlist = array('MessageCommand', 'SubCommand', 'UnsubCommand', + 'FavCommand', 'OnCommand', 'OffCommand'); if (in_array(get_class($cmd), $cmdlist)) { return true; |