]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
New actions for /statuses/friends and /statuses/followers + social graph methods
authorZach Copley <zach@status.net>
Wed, 30 Sep 2009 17:22:26 +0000 (10:22 -0700)
committerZach Copley <zach@status.net>
Wed, 30 Sep 2009 17:22:26 +0000 (10:22 -0700)
actions/apifollowers.php [new file with mode: 0644]
actions/apifriends.php [new file with mode: 0644]
actions/apisubscriptions.php [new file with mode: 0644]
lib/apiauth.php
lib/router.php
lib/twitterapi.php

diff --git a/actions/apifollowers.php b/actions/apifollowers.php
new file mode 100644 (file)
index 0000000..30e3b2d
--- /dev/null
@@ -0,0 +1,85 @@
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Show a user's followers (subscriptions)
+ *
+ * PHP version 5
+ *
+ * LICENCE: This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category  API
+ * @package   StatusNet
+ * @author    Zach Copley <zach@status.net>
+ * @copyright 2009 StatusNet, Inc.
+ * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link      http://status.net/
+ */
+
+if (!defined('STATUSNET')) {
+    exit(1);
+}
+
+require_once INSTALLDIR.'/lib/apibareauth.php';
+
+/**
+ * Ouputs the authenticating user's followers (subscribers), each with
+ * current Twitter-style status inline.  They are ordered by the order
+ * in which they subscribed to the user, 100 at a time.
+ *
+ * @category API
+ * @package  StatusNet
+ * @author   Zach Copley <zach@status.net>
+ * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link     http://status.net/
+ */
+
+class ApiFollowersAction extends ApiSubscriptionsAction
+{
+    /**
+     * Get the user's subscribers (followers) as an array of profiles
+     *
+     * @return array Profiles
+     */
+
+    function getProfiles()
+    {
+        $offset = ($this->page - 1) * $this->count;
+        $limit =  $this->count + 1;
+
+        $subs = null;
+
+        if (isset($this->tag)) {
+            $subs = $this->user->getTaggedSubscribers(
+                $this->tag, $offset, $limit
+            );
+        } else {
+            $subs = $this->user->getSubscribers(
+                $offset,
+                $limit
+            );
+        }
+
+        $profiles = array();
+
+        if (!empty($subs)) {
+            while ($subs->fetch()) {
+                $profiles[] = clone($subs);
+            }
+        }
+
+        return $profiles;
+    }
+
+}
diff --git a/actions/apifriends.php b/actions/apifriends.php
new file mode 100644 (file)
index 0000000..12751a6
--- /dev/null
@@ -0,0 +1,85 @@
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Show a user's friends (subscriptions)
+ *
+ * PHP version 5
+ *
+ * LICENCE: This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category  API
+ * @package   StatusNet
+ * @author    Zach Copley <zach@status.net>
+ * @copyright 2009 StatusNet, Inc.
+ * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link      http://status.net/
+ */
+
+if (!defined('STATUSNET')) {
+    exit(1);
+}
+
+require_once INSTALLDIR.'/lib/apibareauth.php';
+
+/**
+ * Ouputs the authenticating user's friends (subscriptions), each with
+ * current Twitter-style status inline.  They are ordered by the date
+ * in which the user subscribed to them, 100 at a time.
+ *
+ * @category API
+ * @package  StatusNet
+ * @author   Zach Copley <zach@status.net>
+ * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link     http://status.net/
+ */
+
+class ApiFriendsAction extends ApiSubscriptionsAction
+{
+    /**
+     * Get the user's subscriptions (friends) as an array of profiles
+     *
+     * @return array Profiles
+     */
+
+    function getProfiles()
+    {
+        $offset = ($this->page - 1) * $this->count;
+        $limit =  $this->count + 1;
+
+        $subs = null;
+
+        if (isset($this->tag)) {
+            $subs = $this->user->getTaggedSubscriptions(
+                $this->tag, $offset, $limit
+            );
+        } else {
+            $subs = $this->user->getSubscriptions(
+                $offset,
+                $limit
+            );
+        }
+
+        $profiles = array();
+
+        if (!empty($subs)) {
+            while ($subs->fetch()) {
+                $profiles[] = clone($subs);
+            }
+        }
+
+        return $profiles;
+    }
+
+}
diff --git a/actions/apisubscriptions.php b/actions/apisubscriptions.php
new file mode 100644 (file)
index 0000000..78dcd72
--- /dev/null
@@ -0,0 +1,275 @@
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Base class for showing subscription information in the API
+ *
+ * PHP version 5
+ *
+ * LICENCE: This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @category  API
+ * @package   StatusNet
+ * @author    Zach Copley <zach@status.net>
+ * @copyright 2009 StatusNet, Inc.
+ * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link      http://status.net/
+ */
+
+if (!defined('STATUSNET')) {
+    exit(1);
+}
+
+require_once INSTALLDIR.'/lib/apibareauth.php';
+
+/**
+ * This class outputs a list of profiles as Twitter-style user and status objects.
+ * It is used by the API methods /api/statuses/(friends|followers). To support the
+ * social graph methods it also can output a simple list of IDs.
+ *
+ * @category API
+ * @package  StatusNet
+ * @author   Zach Copley <zach@status.net>
+ * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link     http://status.net/
+ */
+
+class ApiSubscriptionsAction extends ApiBareAuthAction
+{
+
+    var $page     = null;
+    var $count    = null;
+    var $user     = null;
+    var $profiles = null;
+    var $format   = null;
+    var $tag      = null;
+    var $lite     = null;
+    var $ids_only = null;
+
+    /**
+     * Take arguments for running
+     *
+     * @param array $args $_REQUEST args
+     *
+     * @return boolean success flag
+     *
+     */
+
+    function prepare($args)
+    {
+        parent::prepare($args);
+
+        $this->page     = (int)$this->arg('page', 1);
+        $this->tag      = $this->arg('tag');
+        $this->format   = $this->arg('format');
+
+        // Note: Twitter no longer supports 'lite'
+        $this->lite     = $this->arg('lite');
+
+        $this->ids_only = $this->arg('ids_only');
+
+        // If called as a social graph method, show 5000 per page, otherwise 100
+
+        $this->count    = isset($this->ids_only) ?
+            5000 : (int)$this->arg('count', 100);
+
+        if ($this->requiresAuth()) {
+            if ($this->checkBasicAuthUser() == false) {
+                return false;
+            }
+        }
+
+        $this->user = $this->getTargetUser($this->arg('id'));
+
+        if (empty($this->user)) {
+            $this->clientError(_('No such user!'), 404, $this->format);
+            return false;
+        }
+
+        $this->profiles = $this->getProfiles();
+
+        return true;
+    }
+
+    /**
+     * Handle the request
+     *
+     * Show the profiles
+     *
+     * @param array $args $_REQUEST data (unused)
+     *
+     * @return void
+     */
+
+    function handle($args)
+    {
+        parent::handle($args);
+
+        if (!in_array($this->format, array('xml', 'json'))) {
+            $this->clientError(_('API method not found!'), $code = 404);
+            return;
+        }
+
+        $this->init_document($this->format);
+
+        if (isset($this->ids_only)) {
+            $this->showIds();
+        } else {
+            $this->showProfiles(isset($this->lite) ? false : true);
+        }
+
+        $this->end_document($this->format);
+    }
+
+    /**
+     * Get profiles - should get overrrided
+     *
+     * @return array Profiles
+     */
+
+    function getProfiles()
+    {
+    }
+
+    /**
+     * Is this action read only?
+     *
+     * @param array $args other arguments
+     *
+     * @return boolean true
+     */
+
+    function isReadOnly($args)
+    {
+        return true;
+    }
+
+    /**
+     * When was this feed last modified?
+     *
+     * @return string datestamp of the latest profile in the stream
+     */
+
+    function lastModified()
+    {
+        if (!empty($this->profiles) && (count($this->profiles) > 0)) {
+            return strtotime($this->profiles[0]->created);
+        }
+
+        return null;
+    }
+
+    /**
+     * An entity tag for this action
+     *
+     * Returns an Etag based on the action name, language, user ID, and
+     * timestamps of the first and last profiles in the subscriptions list
+     * There's also an indicator to show whether this action is being called
+     * as /api/statuses/(friends|followers) or /api/(friends|followers)/ids
+     *
+     * @return string etag
+     */
+
+    function etag()
+    {
+        if (!empty($this->profiles) && (count($this->profiles) > 0)) {
+
+            $last = count($this->profiles) - 1;
+
+            return '"' . implode(
+                ':',
+                array($this->arg('action'),
+                      common_language(),
+                      $this->user->id,
+                      isset($this->ids_only) ? 'IDs' : 'Profiles',
+                      strtotime($this->profiles[0]->created),
+                      strtotime($this->profiles[$last]->created))
+            )
+            . '"';
+        }
+
+        return null;
+    }
+
+    /**
+     * Show the profiles as Twitter-style useres and statuses
+     *
+     * @param boolean $include_statuses Whether to include the latest status
+     *                                  with each user. Default true.
+     *
+     * @return void
+     */
+
+    function showProfiles($include_statuses = true)
+    {
+        switch ($this->format) {
+        case 'xml':
+            $this->elementStart('users', array('type' => 'array'));
+            foreach ($this->profiles as $profile) {
+                $this->show_profile(
+                    $profile,
+                    $this->format,
+                    null,
+                    $include_statuses
+                );
+            }
+            $this->elementEnd('users');
+            break;
+        case 'json':
+            $arrays = array();
+            foreach ($this->profiles as $profile) {
+                $arrays[] = $this->twitter_user_array(
+                    $profile,
+                    $include_statuses
+                );
+            }
+            print json_encode($arrays);
+            break;
+        default:
+            $this->clientError(_('Unsupported format.'));
+            break;
+        }
+    }
+
+    /**
+     * Show the IDs of the profiles only. 5000 per page. To support
+     * the 'social graph' methods: /api/(friends|followers)/ids
+     *
+     * @return void
+     */
+
+    function showIds()
+    {
+        switch ($this->format) {
+        case 'xml':
+            $this->elementStart('ids');
+            foreach ($this->profiles as $profile) {
+                $this->element('id', null, $profile->id);
+            }
+            $this->elementEnd('ids');
+            break;
+        case 'json':
+            $ids = array();
+            foreach ($this->profiles as $profile) {
+                $ids[] = (int)$profile->id;
+            }
+            print json_encode($ids);
+            break;
+        default:
+            $this->clientError(_('Unsupported format.'));
+            break;
+        }
+    }
+
+}
index c1976f964e59df5a54ee8b7e718521837e32d7e9..f0b4b6bf7f44f0fec8e2b1dee8167da559221668 100644 (file)
@@ -45,6 +45,9 @@ require_once INSTALLDIR.'/lib/twitterapi.php';
 
 class ApiAuthAction extends TwitterapiAction
 {
+
+    var $auth_user = null;
+
     /**
      * Does this API resource require authentication?
      *
index 91cdd2cf80e0abb13efc37aba258bd93ee7d022a..b3bb240d9a87f3c8c51f61ea11560f7df4e0cf57 100644 (file)
@@ -314,18 +314,33 @@ class Router
                     'id' => '[a-zA-Z0-9]+',
                     'format' => '(xml|json|rss|atom)'));
 
-        $m->connect('api/statuses/home_timeline',
-                    array('action' => 'apifriendstimeline'));
+        $m->connect('api/statuses/friends.:format',
+                     array('action' => 'ApiFriends',
+                           'format' => '(xml|json)'));
+
+        $m->connect('api/statuses/friends/:id.:format',
+                    array('action' => 'ApiFriends',
+                    'id' => '[a-zA-Z0-9]+',
+                    'format' => '(xml|json)'));
+
+        $m->connect('api/statuses/followers.:format',
+                     array('action' => 'ApiFollowers',
+                           'format' => '(xml|json)'));
+
+        $m->connect('api/statuses/followers/:id.:format',
+                    array('action' => 'ApiFollowers',
+                    'id' => '[a-zA-Z0-9]+',
+                    'format' => '(xml|json)'));
 
         $m->connect('api/statuses/:method',
                     array('action' => 'api',
                           'apiaction' => 'statuses'),
-                    array('method' => '(update|show|friends|followers|featured)(\.(atom|rss|xml|json))?'));
+                    array('method' => '(update|show|featured)(\.(atom|rss|xml|json))?'));
 
         $m->connect('api/statuses/:method/:argument',
                     array('action' => 'api',
                           'apiaction' => 'statuses'),
-                    array('method' => '(show|destroy|friends|followers)'));
+                    array('method' => '(show|destroy)'));
 
         // users
 
@@ -380,29 +395,21 @@ class Router
 
         // Social graph
 
-        $m->connect('api/friends/ids/:argument',
-                    array('action' => 'api',
-                          'apiaction' => 'statuses',
-                          'method' => 'friendsIDs'));
+        $m->connect('api/friends/ids/:id.:format',
+                    array('action' => 'apiFriends',
+                          'ids_only' => true));
 
-        foreach (array('xml', 'json') as $e) {
-            $m->connect('api/friends/ids.'.$e,
-                        array('action' => 'api',
-                              'apiaction' => 'statuses',
-                              'method' => 'friendsIDs.'.$e));
-        }
+        $m->connect('api/followers/ids/:id.:format',
+                    array('action' => 'apiFollowers',
+                          'ids_only' => true));
 
-        $m->connect('api/followers/ids/:argument',
-                    array('action' => 'api',
-                          'apiaction' => 'statuses',
-                          'method' => 'followersIDs'));
+        $m->connect('api/friends/ids.:format',
+                    array('action' => 'apiFriends',
+                          'ids_only' => true));
 
-        foreach (array('xml', 'json') as $e) {
-            $m->connect('api/followers/ids.'.$e,
-                        array('action' => 'api',
-                              'apiaction' => 'statuses',
-                              'method' => 'followersIDs.'.$e));
-        }
+        $m->connect('api/followers/ids.:format',
+                     array('action' => 'apiFollowers',
+                          'ids_only' => true));
 
         // account
 
index 5cf66666883fdc64930cc558c0de93634bca2026..6014a340eb5f9cdce51e5ac7233365b7b7738b5a 100644 (file)
@@ -24,8 +24,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
 class TwitterapiAction extends Action
 {
 
-    var $auth_user;
-
     /**
      * Initialization.
      *