X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=actions%2Ftwitapistatuses.php;h=0c97ada0b115b8327725b864fff495b3a36b8d75;hb=575f70545171f6f5c94214ce88e5b07a1f517810;hp=0d6443f7d02fb912bff9490aaac67fa6195199f5;hpb=8ad7dded2c7371b40df42707dcf401157a9eeba2;p=quix0rs-gnu-social.git diff --git a/actions/twitapistatuses.php b/actions/twitapistatuses.php index 0d6443f7d0..0c97ada0b1 100644 --- a/actions/twitapistatuses.php +++ b/actions/twitapistatuses.php @@ -27,26 +27,41 @@ require_once(INSTALLDIR.'/lib/twitterapi.php'); */ class TwitapistatusesAction extends TwitterapiAction { + function is_readonly() { + + static $write_methods = array( 'update', + 'destroy'); + + $cmdtext = explode('.', $this->arg('method')); + + if (in_array($cmdtext[0], $write_methods)) { + return false; + } + + return true; + } + function public_timeline($args, $apidata) { parent::handle($args); - + $sitename = common_config('site', 'name'); $siteserver = common_config('site', 'server'); $title = sprintf(_("%s public timeline"), $sitename); $id = "tag:$siteserver:Statuses"; $link = common_root_url(); - $subtitle = sprintf(_("%s updates from everyone!"), $sitemap); + $subtitle = sprintf(_("%s updates from everyone!"), $sitename); // Number of public statuses to return by default -- Twitter sends 20 $MAX_PUBSTATUSES = 20; - $notice = DB_DataObject::factory('notice'); + $notice = new Notice(); // FIXME: 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 - # FIXME: bad performance - $notice->whereAdd('EXISTS (SELECT user.id from user where user.id = notice.profile_id)'); + # XXX: sub-optimal performance + + $notice->is_local = 1; $notice->orderBy('created DESC, notice.id DESC'); $notice->limit($MAX_PUBSTATUSES); $cnt = $notice->find(); @@ -79,25 +94,29 @@ class TwitapistatusesAction extends TwitterapiAction { } function show_xml_timeline($notice) { - - header('Content-Type: application/xml; charset=utf-8'); - common_start_xml(); + + $this->init_document('xml'); common_element_start('statuses', array('type' => 'array')); - - while ($notice->fetch()) { - $twitter_status = $this->twitter_status_array($notice); - $this->show_twitter_xml_status($twitter_status); + + if (is_array($notice)) { + foreach ($notice as $n) { + $twitter_status = $this->twitter_status_array($n); + $this->show_twitter_xml_status($twitter_status); + } + } else { + while ($notice->fetch()) { + $twitter_status = $this->twitter_status_array($notice); + $this->show_twitter_xml_status($twitter_status); + } } common_element_end('statuses'); - common_end_xml(); - } + $this->end_document('xml'); + } function show_rss_timeline($notice, $title, $id, $link, $subtitle) { - header("Content-Type: application/rss+xml; charset=utf-8"); - - $this->init_twitter_rss(); + $this->init_document('rss'); common_element_start('channel'); common_element('title', NULL, $title); @@ -106,46 +125,69 @@ class TwitapistatusesAction extends TwitterapiAction { common_element('language', NULL, 'en-us'); common_element('ttl', NULL, '40'); - while ($notice->fetch()) { - $entry = $this->twitter_rss_entry_array($notice); - $this->show_twitter_rss_item($entry); + + if (is_array($notice)) { + foreach ($notice as $n) { + $entry = $this->twitter_rss_entry_array($n); + $this->show_twitter_rss_item($entry); + } + } else { + while ($notice->fetch()) { + $entry = $this->twitter_rss_entry_array($notice); + $this->show_twitter_rss_item($entry); + } } - + common_element_end('channel'); - $this->end_twitter_rss(); + $this->end_twitter_rss(); } function show_atom_timeline($notice, $title, $id, $link, $subtitle=NULL) { - header('Content-Type: application/atom+xml; charset=utf-8'); - - $this->init_twitter_atom(); + $this->init_document('atom'); common_element('title', NULL, $title); common_element('id', NULL, $id); common_element('link', array('href' => $link, 'rel' => 'alternate', 'type' => 'text/html'), NULL); common_element('subtitle', NULL, $subtitle); - while ($notice->fetch()) { - $entry = $this->twitter_rss_entry_array($notice); - $this->show_twitter_atom_entry($entry); + if (is_array($notice)) { + foreach ($notice as $n) { + $entry = $this->twitter_rss_entry_array($n); + $this->show_twitter_atom_entry($entry); + } + } else { + while ($notice->fetch()) { + $entry = $this->twitter_rss_entry_array($notice); + $this->show_twitter_atom_entry($entry); + } } - $this->end_twitter_atom(); + $this->end_document('atom'); + } function show_json_timeline($notice) { - header('Content-Type: application/json; charset=utf-8'); + $this->init_document('json'); $statuses = array(); - while ($notice->fetch()) { - $twitter_status = $this->twitter_status_array($notice); - array_push($statuses, $twitter_status); - } + if (is_array($notice)) { + foreach ($notice as $n) { + $twitter_status = $this->twitter_status_array($n); + array_push($statuses, $twitter_status); + } + } else { + while ($notice->fetch()) { + $twitter_status = $this->twitter_status_array($notice); + array_push($statuses, $twitter_status); + } + } $this->show_twitter_json_statuses($statuses); + + $this->end_document('json'); } /* @@ -195,21 +237,7 @@ class TwitapistatusesAction extends TwitterapiAction { $link = common_local_url('all', array('nickname' => $user->nickname)); $subtitle = sprintf(_("Updates from %s and friends on %s!"), $user->nickname, $sitename); - $notice = new Notice(); - - # XXX: chokety and bad - - $notice->whereAdd('EXISTS (SELECT subscribed from subscription where subscriber = '.$profile->id.' and subscribed = notice.profile_id)', 'OR'); - $notice->whereAdd('profile_id = ' . $profile->id, 'OR'); - - # XXX: since - # XXX: since_id - - $notice->orderBy('created DESC, notice.id DESC'); - - $notice->limit((($page-1)*20), $count); - - $cnt = $notice->find(); + $notice = $user->noticesWithFriends(($page-1)*20, $count); switch($apidata['content-type']) { case 'xml': @@ -259,11 +287,40 @@ class TwitapistatusesAction extends TwitterapiAction { function user_timeline($args, $apidata) { parent::handle($args); - $id = $this->arg('id'); + $user = null; + + // function was called with an argument /statuses/user_timeline/api_arg.format + if (isset($apidata['api_arg'])) { + + if (is_numeric($apidata['api_arg'])) { + $user = User::staticGet($apidata['api_arg']); + } else { + $nickname = common_canonical_nickname($apidata['api_arg']); + $user = User::staticGet('nickname', $nickname); + } + } else { + + // if no user was specified, then we'll use the authenticated user + $user = $apidata['user']; + } + + if (!$user) { + // Set the user to be the auth user if asked-for can't be found + // honestly! This is what Twitter does, I swear --Zach + $user = $apidata['user']; + } + + $profile = $user->getProfile(); + + if (!$profile) { + common_server_error(_('User has no profile.')); + exit(); + } + $count = $this->arg('count'); $since = $this->arg('since'); $since_id = $this->arg('since_id'); - + if (!$page) { $page = 1; } @@ -271,16 +328,7 @@ class TwitapistatusesAction extends TwitterapiAction { if (!$count) { $count = 20; } - - $user = $this->get_user($id, $apidata['user']); - - if (!$user) { - $this->client_error(_('No such user'), 404); - return; - } - - $profile = $user->getProfile(); - + $sitename = common_config('site', 'name'); $siteserver = common_config('site', 'server'); @@ -321,48 +369,15 @@ class TwitapistatusesAction extends TwitterapiAction { exit(); } - - function show($args, $apidata) { - parent::handle($args); - - $id = $apidata['api_arg']; - $notice = Notice::staticGet($id); - - if ($notice) { - - if ($apidata['content-type'] == 'xml') { - $this->show_single_xml_status($notice); - } elseif ($apidata['content-type'] == 'json') { - $this->show_single_json_status($notice); - } - } else { - header('HTTP/1.1 404 Not Found'); - } - - exit(); - } - - function show_single_xml_status($notice) { - header('Content-Type: application/xml; charset=utf-8'); - common_start_xml(); - $twitter_status = $this->twitter_status_array($notice); - $this->show_twitter_xml_status($twitter_status); - common_end_xml(); - exit(); - } - - function show_single_json_status($notice) { - header('Content-Type: application/json; charset=utf-8'); - $status = $this->twitter_status_array($notice); - $this->show_twitter_json_statuses($status); - exit(); - } function update($args, $apidata) { parent::handle($args); $user = $apidata['user']; + $this->is_readonly(); + + $notice = DB_DataObject::factory('notice'); $notice->profile_id = $user->id; # user id *is* profile id @@ -389,7 +404,8 @@ class TwitapistatusesAction extends TwitterapiAction { } $notice->rendered = common_render_content($notice->content, $notice); - + $notice->is_local = 1; + $id = $notice->insert(); if (!$id) { @@ -436,9 +452,83 @@ class TwitapistatusesAction extends TwitterapiAction { ID. Ex: http://server/api/statuses/replies.xml?since_id=12345 */ function replies($args, $apidata) { + parent::handle($args); - common_server_error("API method under construction.", $code=501); + + $since = $this->arg('since'); + + $count = $this->arg('count'); + $page = $this->arg('page'); + + $user = $apidata['user']; + $profile = $user->getProfile(); + + $sitename = common_config('site', 'name'); + $siteserver = common_config('site', 'server'); + + $title = sprintf(_("%s / Updates replying to %s"), $sitename, $user->nickname); + $id = "tag:$siteserver:replies:".$user->id; + $link = common_local_url('replies', array('nickname' => $user->nickname)); + $subtitle = "gar"; + $subtitle = sprintf(_("%s updates that reply to updates from %s / %s."), $sitename, $user->nickname, $profile->getBestName()); + + if (!$page) { + $page = 1; + } + + if (!$count) { + $count = 20; + } + + $reply = new Reply(); + + $reply->profile_id = $user->id; + + $reply->orderBy('modified DESC'); + + $page = ($this->arg('page')) ? ($this->arg('page')+0) : 1; + + $reply->limit((($page-1)*20), $count); + + $cnt = $reply->find(); + + $notices = array(); + + if ($cnt) { + while ($reply->fetch()) { + $notice = new Notice(); + $notice->id = $reply->notice_id; + $result = $notice->find(true); + if (!$result) { + continue; + } + $notices[] = clone($notice); + } + } + + switch($apidata['content-type']) { + case 'xml': + $this->show_xml_timeline($notices); + break; + case 'rss': + $this->show_rss_timeline($notices, $title, $id, $link, $subtitle); + break; + case 'atom': + $this->show_atom_timeline($notices, $title, $id, $link, $subtitle); + break; + case 'json': + $this->show_json_timeline($notices); + break; + default: + common_user_error("API method not found!", $code = 404); + } + + + exit(); + + } + /* @@ -486,7 +576,7 @@ class TwitapistatusesAction extends TwitterapiAction { */ function friends($args, $apidata) { parent::handle($args); - common_server_error("API method under construction.", $code=501); + return $this->subscriptions($apidata, 'subscribed', 'subscriber'); } /* @@ -508,7 +598,99 @@ class TwitapistatusesAction extends TwitterapiAction { */ function followers($args, $apidata) { parent::handle($args); - common_server_error("API method under construction.", $code=501); + + return $this->subscriptions($apidata, 'subscriber', 'subscribed'); + } + + function subscriptions($apidata, $other_attr, $user_attr) { + + $user = $this->get_subs_user($apidata); + + # XXX: id + # XXX: lite + + $page = $this->trimmed('page'); + + if (!$page || !is_numeric($page)) { + $page = 1; + } + + $profile = $user->getProfile(); + + if (!$profile) { + common_server_error(_('User has no profile.')); + return; + } + + $sub = new Subscription(); + $sub->$user_attr = $profile->id; + $sub->orderBy('created DESC'); + $sub->limit(($page-1)*100, 100); + + $others = array(); + + if ($sub->find()) { + while ($sub->fetch()) { + $others[] = Profile::staticGet($sub->$other_attr); + } + } else { + // user has no followers + } + + $type = $apidata['content-type']; + + $this->init_document($type); + $this->show_profiles($others, $type); + $this->end_document($type); + exit(); + } + + function get_subs_user($apidata) { + + // function was called with an argument /statuses/user_timeline/api_arg.format + if (isset($apidata['api_arg'])) { + + if (is_numeric($apidata['api_arg'])) { + $user = User::staticGet($apidata['api_arg']); + } else { + $nickname = common_canonical_nickname($apidata['api_arg']); + $user = User::staticGet('nickname', $nickname); + } + } else { + + // if no user was specified, then we'll use the authenticated user + $user = $apidata['user']; + } + + if (!$user) { + // Set the user to be the auth user if asked-for can't be found + // honestly! This is what Twitter does, I swear --Zach + $user = $apidata['user']; + } + + return $user; + } + + function show_profiles($profiles, $type) { + switch ($type) { + case 'xml': + common_element_start('users', array('type' => 'array')); + foreach ($profiles as $profile) { + $this->show_profile($profile); + } + common_element_end('users'); + break; + case 'json': + $arrays = array(); + foreach ($profiles as $profile) { + $arrays[] = $this->twitter_user_array($profile, true); + } + print json_encode($arrays); + break; + default: + $this->client_error(_('unsupported file type')); + exit(); + } } /*