*/
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();
}
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);
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');
}
/*
$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':
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;
}
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');
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
}
$notice->rendered = common_render_content($notice->content, $notice);
-
+ $notice->is_local = 1;
+
$id = $notice->insert();
if (!$id) {
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();
+
+
}
+
/*
*/
function friends($args, $apidata) {
parent::handle($args);
- common_server_error("API method under construction.", $code=501);
+ return $this->subscriptions($apidata, 'subscribed', 'subscriber');
}
/*
*/
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();
+ }
}
/*