]> git.mxchange.org Git - quix0rs-gnu-social.git/blobdiff - actions/twitapistatuses.php
if-else instead of ?:
[quix0rs-gnu-social.git] / actions / twitapistatuses.php
index 0d6443f7d02fb912bff9490aaac67fa6195199f5..0c97ada0b115b8327725b864fff495b3a36b8d75 100644 (file)
@@ -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();
+               }
        }
        
        /*