]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Renamed and moved stuff around to better match Twitter's API organization
authorZach Copley <zach@status.net>
Fri, 2 Oct 2009 01:19:59 +0000 (18:19 -0700)
committerZach Copley <zach@status.net>
Fri, 2 Oct 2009 01:19:59 +0000 (18:19 -0700)
20 files changed:
actions/apidestroy.php [deleted file]
actions/apifollowers.php [deleted file]
actions/apifriends.php [deleted file]
actions/apifriendstimeline.php [deleted file]
actions/apimentions.php [deleted file]
actions/apipublictimeline.php [deleted file]
actions/apishow.php [deleted file]
actions/apistatusesdestroy.php [new file with mode: 0644]
actions/apistatusesshow.php [new file with mode: 0644]
actions/apistatusesupdate.php [new file with mode: 0644]
actions/apitimelinefriends.php [new file with mode: 0644]
actions/apitimelinementions.php [new file with mode: 0644]
actions/apitimelinepublic.php [new file with mode: 0644]
actions/apitimelineuser.php [new file with mode: 0644]
actions/apiupdate.php [deleted file]
actions/apiuserfollowers.php [new file with mode: 0644]
actions/apiuserfriends.php [new file with mode: 0644]
actions/apiusertimeline.php [deleted file]
actions/twitapistatuses.php [deleted file]
lib/router.php

diff --git a/actions/apidestroy.php b/actions/apidestroy.php
deleted file mode 100644 (file)
index a3b6bf6..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-<?php
-/**
- * StatusNet, the distributed open-source microblogging tool
- *
- * Destroy a notice through 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/apiauth.php';
-
-/**
- * Deletes one of the authenticating user's statuses (notices).
- *
- * @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 ApiDestroyAction extends ApiAuthAction
-{
-
-    var $user                  = null;
-    var $status                = null;
-    var $format                = null;
-
-    /**
-     * Take arguments for running
-     *
-     * @param array $args $_REQUEST args
-     *
-     * @return boolean success flag
-     *
-     */
-
-    function prepare($args)
-    {
-        parent::prepare($args);
-
-        if ($this->requiresAuth()) {
-            if ($this->checkBasicAuthUser() == false) {
-                return false;
-            }
-        }
-
-        $this->user = $this->auth_user;
-        $this->notice_id = (int)$this->trimmed('id');
-
-        if (empty($notice_id)) {
-            $this->notice_id = (int)$this->arg('id');
-        }
-
-        $this->format = $this->arg('format');
-        $this->notice = Notice::staticGet((int)$this->notice_id);
-
-        return true;
-     }
-
-    /**
-     * Handle the request
-     *
-     * Delete the notice and all related replies
-     *
-     * @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;
-        }
-
-         if (!in_array($_SERVER['REQUEST_METHOD'], array('POST', 'DELETE'))) {
-             $this->clientError(_('This method requires a POST or DELETE.'),
-                 400, $this->format);
-             return;
-         }
-
-         if (empty($this->notice)) {
-             $this->clientError(_('No status found with that ID.'),
-                 404, $this->format);
-             return;
-         }
-
-         if ($this->user->id == $this->notice->profile_id) {
-             $replies = new Reply;
-             $replies->get('notice_id', $this->notice_id);
-             $replies->delete();
-             $this->notice->delete();
-
-             if ($this->format == 'xml') {
-                 $this->show_single_xml_status($this->notice);
-             } elseif ($this->format == 'json') {
-                 $this->show_single_json_status($this->notice);
-             }
-         } else {
-             $this->clientError(_('You may not delete another user\'s status.'),
-                 403, $this->format);
-         }
-
-        $this->showNotice();
-    }
-
-    /**
-     * Show the deleted notice
-     *
-     * @return void
-     */
-
-    function showNotice()
-    {
-        if (!empty($this->notice)) {
-            if ($this->format == 'xml') {
-                $this->show_single_xml_status($this->notice);
-            } elseif ($this->format == 'json') {
-                $this->show_single_json_status($this->notice);
-            }
-        }
-    }
-
-}
diff --git a/actions/apifollowers.php b/actions/apifollowers.php
deleted file mode 100644 (file)
index b216cce..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-<?php
-/**
- * StatusNet, the distributed open-source microblogging tool
- *
- * Show a user's followers (subscribers)
- *
- * 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
deleted file mode 100644 (file)
index 12751a6..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-<?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/apifriendstimeline.php b/actions/apifriendstimeline.php
deleted file mode 100644 (file)
index be0cf75..0000000
+++ /dev/null
@@ -1,255 +0,0 @@
-<?php
-/**
- * StatusNet, the distributed open-source microblogging tool
- *
- * Show the friends timeline
- *
- * 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';
-
-/**
- * Returns the most recent notices (default 20) posted by the target user.
- * This is the equivalent of 'You and friends' page accessed via Web.
- *
- * @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 ApiFriendsTimelineAction extends ApiBareAuthAction
-{
-
-    var $user     = null;
-    var $notices  = null;
-    var $count    = null;
-    var $max_id   = null;
-    var $since_id = null;
-    var $since    = null;
-    var $format   = 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->count    = (int)$this->arg('count', 20);
-        $this->max_id   = (int)$this->arg('max_id', 0);
-        $this->since_id = (int)$this->arg('since_id', 0);
-        $this->since    = $this->arg('since');
-        $this->format   = $this->arg('format');
-
-        if ($this->requiresAuth()) {
-            if ($this->checkBasicAuthUser() == false) {
-                return;
-            }
-        }
-
-        $this->user = $this->getTargetUser($this->arg('id'));
-
-        if (empty($this->user)) {
-            $this->clientError(_('No such user!'), 404, $this->format);
-            return;
-        }
-
-        $this->notices = $this->getNotices();
-
-        return true;
-    }
-
-    /**
-     * Handle the request
-     *
-     * Just show the notices
-     *
-     * @param array $args $_REQUEST data (unused)
-     *
-     * @return void
-     */
-
-    function handle($args)
-    {
-        parent::handle($args);
-        $this->showTimeline();
-    }
-
-    /**
-     * Show the timeline of notices
-     *
-     * @return void
-     */
-
-    function showTimeline()
-    {
-        $profile    = $this->user->getProfile();
-        $sitename   = common_config('site', 'name');
-        $title      = sprintf(_("%s and friends"), $this->user->nickname);
-        $taguribase = common_config('integration', 'taguri');
-        $id         = "tag:$taguribase:FriendsTimeline:" . $this->user->id;
-        $link       = common_local_url(
-            'all', array('nickname' => $this->user->nickname)
-        );
-        $subtitle   = sprintf(
-            _('Updates from %1$s and friends on %2$s!'),
-            $this->user->nickname, $sitename
-        );
-
-        switch($this->format) {
-        case 'xml':
-            $this->show_xml_timeline($this->notices);
-            break;
-        case 'rss':
-            $this->show_rss_timeline($this->notices, $title, $link, $subtitle);
-            break;
-        case 'atom':
-
-            $target_id = $this->arg('id');
-
-            if (isset($target_id)) {
-                $selfuri = common_root_url() .
-                    'api/statuses/friends_timeline/' .
-                    $target_id . '.atom';
-            } else {
-                $selfuri = common_root_url() .
-                    'api/statuses/friends_timeline.atom';
-            }
-
-            $this->show_atom_timeline(
-                $this->notices, $title, $id, $link,
-                $subtitle, null, $selfuri
-            );
-            break;
-        case 'json':
-            $this->show_json_timeline($this->notices);
-            break;
-        default:
-            $this->clientError(_('API method not found!'), $code = 404);
-            break;
-        }
-    }
-
-    /**
-     * Get notices
-     *
-     * @return array notices
-     */
-
-    function getNotices()
-    {
-        $notices = array();
-
-        if (!empty($this->auth_user) && $this->auth_user->id == $this->user->id) {
-            $notice = $this->user->noticeInbox(
-                ($this->page-1) * $this->count,
-                $this->count, $this->since_id,
-                $this->max_id, $this->since
-            );
-        } else {
-            $notice = $this->user->noticesWithFriends(
-                ($this->page-1) * $this->count,
-                $this->count, $this->since_id,
-                $this->max_id, $this->since
-            );
-        }
-
-        while ($notice->fetch()) {
-            $notices[] = clone($notice);
-        }
-
-        return $notices;
-    }
-
-    /**
-     * 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 notice in the stream
-     */
-
-    function lastModified()
-    {
-        if (!empty($this->notices) && (count($this->notices) > 0)) {
-            return strtotime($this->notices[0]->created);
-        }
-
-        return null;
-    }
-
-    /**
-     * An entity tag for this stream
-     *
-     * Returns an Etag based on the action name, language, user ID, and
-     * timestamps of the first and last notice in the timeline
-     *
-     * @return string etag
-     */
-
-    function etag()
-    {
-        if (!empty($this->notices) && (count($this->notices) > 0)) {
-
-            $last = count($this->notices) - 1;
-
-            return '"' . implode(
-                ':',
-                array($this->arg('action'),
-                      common_language(),
-                      $this->user->id,
-                      strtotime($this->notices[0]->created),
-                      strtotime($this->notices[$last]->created))
-            )
-            . '"';
-        }
-
-        return null;
-    }
-
-}
diff --git a/actions/apimentions.php b/actions/apimentions.php
deleted file mode 100644 (file)
index 43e93a9..0000000
+++ /dev/null
@@ -1,234 +0,0 @@
-<?php
-/**
- * StatusNet, the distributed open-source microblogging tool
- *
- * Show notices mentioning a user (@nickname)
- *
- * 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';
-
-/**
- * Returns the most recent (default 20) mentions (status containing @nickname)
- *
- * @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 ApiMentionsAction extends ApiBareAuthAction
-{
-
-    var $user    = null;
-    var $notices = 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->count    = (int)$this->arg('count', 20);
-        $this->max_id   = (int)$this->arg('max_id', 0);
-        $this->since_id = (int)$this->arg('since_id', 0);
-        $this->since    = $this->arg('since');
-
-        if ($this->requiresAuth()) {
-            if ($this->checkBasicAuthUser() == false) {
-                return;
-            }
-        }
-
-        $this->user = $this->getTargetUser($this->arg('id'));
-
-        if (empty($this->user)) {
-            $this->clientError(_('No such user!'), 404, $this->arg('format'));
-            return;
-        }
-
-        $this->notices = $this->getNotices();
-
-        return true;
-    }
-
-    /**
-     * Handle the request
-     *
-     * Just show the notices
-     *
-     * @param array $args $_REQUEST data (unused)
-     *
-     * @return void
-     */
-
-    function handle($args)
-    {
-        parent::handle($args);
-        $this->showTimeline();
-    }
-
-    /**
-     * Show the timeline of notices
-     *
-     * @return void
-     */
-
-    function showTimeline()
-    {
-        $profile = $this->user->getProfile();
-
-        $sitename   = common_config('site', 'name');
-        $title      = sprintf(
-            _('%1$s / Updates mentioning %2$s'),
-            $sitename, $this->user->nickname
-        );
-        $taguribase = common_config('integration', 'taguri');
-        $id         = "tag:$taguribase:Mentions:" . $this->user->id;
-        $link       = common_local_url(
-            'replies',
-            array('nickname' => $this->user->nickname)
-        );
-        $subtitle   = sprintf(
-            _('%1$s updates that reply to updates from %2$s / %3$s.'),
-            $sitename, $this->user->nickname, $profile->getBestName()
-        );
-
-        switch($this->arg('format')) {
-        case 'xml':
-            $this->show_xml_timeline($this->notices);
-            break;
-        case 'rss':
-            $this->show_rss_timeline($this->notices, $title, $link, $subtitle);
-            break;
-        case 'atom':
-            $selfuri = common_root_url() .
-                ltrim($_SERVER['QUERY_STRING'], 'p=');
-            $this->show_atom_timeline(
-                $this->notices, $title, $id, $link, $subtitle,
-                null, $selfuri
-            );
-            break;
-        case 'json':
-            $this->show_json_timeline($this->notices);
-            break;
-        default:
-            $this->clientError(_('API method not found!'), $code = 404);
-            break;
-        }
-    }
-
-    /**
-     * Get notices
-     *
-     * @return array notices
-     */
-
-    function getNotices()
-    {
-        $notices = array();
-
-        $notice = $this->user->getReplies(
-            ($this->page - 1) * $this->count, $this->count,
-            $this->since_id, $this->max_id, $this->since
-        );
-
-        while ($notice->fetch()) {
-            $notices[] = clone($notice);
-        }
-
-        return $notices;
-    }
-
-    /**
-     * 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 notice in the stream
-     */
-
-    function lastModified()
-    {
-        if (!empty($this->notices) && (count($this->notices) > 0)) {
-            return strtotime($this->notices[0]->created);
-        }
-
-        return null;
-    }
-
-    /**
-     * An entity tag for this stream
-     *
-     * Returns an Etag based on the action name, language, user ID, and
-     * timestamps of the first and last notice in the timeline
-     *
-     * @return string etag
-     */
-
-    function etag()
-    {
-        if (!empty($this->notices) && (count($this->notices) > 0)) {
-
-            $last = count($this->notices) - 1;
-
-            return '"' . implode(
-                ':',
-                array($this->arg('action'),
-                      common_language(),
-                      $this->user->id,
-                      strtotime($this->notices[0]->created),
-                      strtotime($this->notices[$last]->created))
-            )
-            . '"';
-        }
-
-        return null;
-    }
-
-}
diff --git a/actions/apipublictimeline.php b/actions/apipublictimeline.php
deleted file mode 100644 (file)
index 2be979e..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-<?php
-/**
- * StatusNet, the distributed open-source microblogging tool
- *
- * Show the public timeline
- *
- * 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/twitterapi.php';
-
-/**
- * Returns the most recent notices (default 20) posted by everybody
- *
- * @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 ApiPublicTimelineAction extends TwitterapiAction
-{
-
-    var $notices = 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->count    = (int)$this->arg('count', 20);
-        $this->max_id   = (int)$this->arg('max_id', 0);
-        $this->since_id = (int)$this->arg('since_id', 0);
-        $this->since    = $this->arg('since');
-
-        $this->notices = $this->getNotices();
-
-        return true;
-    }
-
-    /**
-     * Handle the request
-     *
-     * Just show the notices
-     *
-     * @param array $args $_REQUEST data (unused)
-     *
-     * @return void
-     */
-
-    function handle($args)
-    {
-        parent::handle($args);
-        $this->showTimeline();
-    }
-
-    /**
-     * Show the timeline of notices
-     *
-     * @return void
-     */
-
-    function showTimeline()
-    {
-        $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);
-
-        switch($this->arg('format')) {
-        case 'xml':
-            $this->show_xml_timeline($this->notices);
-            break;
-        case 'rss':
-            $this->show_rss_timeline($this->notices, $title, $link, $subtitle);
-            break;
-        case 'atom':
-            $selfuri = common_root_url() . 'api/statuses/public_timeline.atom';
-            $this->show_atom_timeline(
-                $this->notices, $title, $id, $link,
-                $subtitle, null, $selfuri
-            );
-            break;
-        case 'json':
-            $this->show_json_timeline($this->notices);
-            break;
-        default:
-            $this->clientError(_('API method not found!'), $code = 404);
-            break;
-        }
-    }
-
-    /**
-     * Get notices
-     *
-     * @return array notices
-     */
-
-    function getNotices()
-    {
-        $notices = array();
-
-        $notice = Notice::publicStream(
-            ($this->page - 1) * $this->count, $this->count, $this->since_id,
-            $this->max_id, $this->since
-        );
-
-        while ($notice->fetch()) {
-            $notices[] = clone($notice);
-        }
-
-        return $notices;
-    }
-
-    /**
-     * 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 notice in the stream
-     */
-
-    function lastModified()
-    {
-        if (!empty($this->notices) && (count($this->notices) > 0)) {
-            return strtotime($this->notices[0]->created);
-        }
-
-        return null;
-    }
-
-    /**
-     * An entity tag for this stream
-     *
-     * Returns an Etag based on the action name, language, and
-     * timestamps of the first and last notice in the timeline
-     *
-     * @return string etag
-     */
-
-    function etag()
-    {
-        if (!empty($this->notices) && (count($this->notices) > 0)) {
-
-            $last = count($this->notices) - 1;
-
-            return '"' . implode(
-                ':',
-                array($this->arg('action'),
-                      common_language(),
-                      strtotime($this->notices[0]->created),
-                      strtotime($this->notices[$last]->created))
-            )
-            . '"';
-        }
-
-        return null;
-    }
-
-}
diff --git a/actions/apishow.php b/actions/apishow.php
deleted file mode 100644 (file)
index 952c7f5..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-<?php
-/**
- * StatusNet, the distributed open-source microblogging tool
- *
- * Show a notice (as a Twitter-style status)
- *
- * 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/twitterapi.php';
-
-/**
- * Returns the notice specified by id as a Twitter-style status and inline user
- *
- * @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 ApiShowAction extends TwitterapiAction
-{
-
-    var $notice_id = null;
-    var $notice    = null;
-    var $format    = null;
-
-    /**
-     * Take arguments for running
-     *
-     * @param array $args $_REQUEST args
-     *
-     * @return boolean success flag
-     *
-     */
-
-    function prepare($args)
-    {
-        parent::prepare($args);
-
-        // 'id' is an undocumented parameter in Twitter's API. Several
-        // clients make use of it, so we support it too.
-
-        // show.json?id=12345 takes precedence over /show/12345.json
-
-        $this->notice_id = (int)$this->trimmed('id');
-
-        if (empty($notice_id)) {
-            $this->notice_id = (int)$this->arg('id');
-        }
-
-        $this->format = $this->arg('format');
-        $this->notice = Notice::staticGet((int)$this->notice_id);
-
-        return true;
-    }
-
-    /**
-     * Handle the request
-     *
-     * Check the format and show the notice
-     *
-     * @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->showNotice();
-    }
-
-    /**
-     * Show the notice
-     *
-     * @return void
-     */
-
-    function showNotice()
-    {
-        if (!empty($this->notice)) {
-            if ($this->format == 'xml') {
-                $this->show_single_xml_status($this->notice);
-            } elseif ($this->format == 'json') {
-                $this->show_single_json_status($this->notice);
-            }
-        } else {
-
-            // XXX: Twitter just sets a 404 header and doens't bother
-            // to return an err msg
-
-            $deleted = Deleted_notice::staticGet($this->notice_id);
-
-            if (!empty($deleted)) {
-                $this->clientError(
-                    _('Status deleted.'),
-                    410,
-                    $this->format
-                );
-            } else {
-                $this->clientError(
-                    _('No status with that ID found.'),
-                    404,
-                    $this->format
-                );
-            }
-        }
-    }
-
-    /**
-     * Is this action read only?
-     *
-     * @param array $args other arguments
-     *
-     * @return boolean true
-     */
-
-    function isReadOnly($args)
-    {
-        return true;
-    }
-
-    /**
-     * When was this notice last modified?
-     *
-     * @return string datestamp of the latest notice in the stream
-     */
-
-    function lastModified()
-    {
-        if (!empty($this->notice)) {
-            return strtotime($this->notice->created);
-        }
-
-        return null;
-    }
-
-    /**
-     * An entity tag for this notice
-     *
-     * Returns an Etag based on the action name, language, and
-     * timestamps of the notice
-     *
-     * @return string etag
-     */
-
-    function etag()
-    {
-        if (!empty($this->notice)) {
-
-            return '"' . implode(
-                ':',
-                array($this->arg('action'),
-                      common_language(),
-                      $this->notice->id,
-                      strtotime($this->notice->created))
-            )
-            . '"';
-        }
-
-        return null;
-    }
-
-}
diff --git a/actions/apistatusesdestroy.php b/actions/apistatusesdestroy.php
new file mode 100644 (file)
index 0000000..ae0f4c4
--- /dev/null
@@ -0,0 +1,152 @@
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Destroy a notice through 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/apiauth.php';
+
+/**
+ * Deletes one of the authenticating user's statuses (notices).
+ *
+ * @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 ApiStatusesDestroyAction extends ApiAuthAction
+{
+
+    var $user                  = null;
+    var $status                = null;
+    var $format                = null;
+
+    /**
+     * Take arguments for running
+     *
+     * @param array $args $_REQUEST args
+     *
+     * @return boolean success flag
+     *
+     */
+
+    function prepare($args)
+    {
+        parent::prepare($args);
+
+        if ($this->requiresAuth()) {
+            if ($this->checkBasicAuthUser() == false) {
+                return false;
+            }
+        }
+
+        $this->user = $this->auth_user;
+        $this->notice_id = (int)$this->trimmed('id');
+
+        if (empty($notice_id)) {
+            $this->notice_id = (int)$this->arg('id');
+        }
+
+        $this->format = $this->arg('format');
+        $this->notice = Notice::staticGet((int)$this->notice_id);
+
+        return true;
+     }
+
+    /**
+     * Handle the request
+     *
+     * Delete the notice and all related replies
+     *
+     * @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;
+        }
+
+         if (!in_array($_SERVER['REQUEST_METHOD'], array('POST', 'DELETE'))) {
+             $this->clientError(_('This method requires a POST or DELETE.'),
+                 400, $this->format);
+             return;
+         }
+
+         if (empty($this->notice)) {
+             $this->clientError(_('No status found with that ID.'),
+                 404, $this->format);
+             return;
+         }
+
+         if ($this->user->id == $this->notice->profile_id) {
+             $replies = new Reply;
+             $replies->get('notice_id', $this->notice_id);
+             $replies->delete();
+             $this->notice->delete();
+
+             if ($this->format == 'xml') {
+                 $this->show_single_xml_status($this->notice);
+             } elseif ($this->format == 'json') {
+                 $this->show_single_json_status($this->notice);
+             }
+         } else {
+             $this->clientError(_('You may not delete another user\'s status.'),
+                 403, $this->format);
+         }
+
+        $this->showNotice();
+    }
+
+    /**
+     * Show the deleted notice
+     *
+     * @return void
+     */
+
+    function showNotice()
+    {
+        if (!empty($this->notice)) {
+            if ($this->format == 'xml') {
+                $this->show_single_xml_status($this->notice);
+            } elseif ($this->format == 'json') {
+                $this->show_single_json_status($this->notice);
+            }
+        }
+    }
+
+}
diff --git a/actions/apistatusesshow.php b/actions/apistatusesshow.php
new file mode 100644 (file)
index 0000000..55eea23
--- /dev/null
@@ -0,0 +1,196 @@
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Show a notice (as a Twitter-style status)
+ *
+ * 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/twitterapi.php';
+
+/**
+ * Returns the notice specified by id as a Twitter-style status and inline user
+ *
+ * @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 ApiStatusesShowAction extends TwitterapiAction
+{
+
+    var $notice_id = null;
+    var $notice    = null;
+    var $format    = null;
+
+    /**
+     * Take arguments for running
+     *
+     * @param array $args $_REQUEST args
+     *
+     * @return boolean success flag
+     *
+     */
+
+    function prepare($args)
+    {
+        parent::prepare($args);
+
+        // 'id' is an undocumented parameter in Twitter's API. Several
+        // clients make use of it, so we support it too.
+
+        // show.json?id=12345 takes precedence over /show/12345.json
+
+        $this->notice_id = (int)$this->trimmed('id');
+
+        if (empty($notice_id)) {
+            $this->notice_id = (int)$this->arg('id');
+        }
+
+        $this->format = $this->arg('format');
+        $this->notice = Notice::staticGet((int)$this->notice_id);
+
+        return true;
+    }
+
+    /**
+     * Handle the request
+     *
+     * Check the format and show the notice
+     *
+     * @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->showNotice();
+    }
+
+    /**
+     * Show the notice
+     *
+     * @return void
+     */
+
+    function showNotice()
+    {
+        if (!empty($this->notice)) {
+            if ($this->format == 'xml') {
+                $this->show_single_xml_status($this->notice);
+            } elseif ($this->format == 'json') {
+                $this->show_single_json_status($this->notice);
+            }
+        } else {
+
+            // XXX: Twitter just sets a 404 header and doens't bother
+            // to return an err msg
+
+            $deleted = Deleted_notice::staticGet($this->notice_id);
+
+            if (!empty($deleted)) {
+                $this->clientError(
+                    _('Status deleted.'),
+                    410,
+                    $this->format
+                );
+            } else {
+                $this->clientError(
+                    _('No status with that ID found.'),
+                    404,
+                    $this->format
+                );
+            }
+        }
+    }
+
+    /**
+     * Is this action read only?
+     *
+     * @param array $args other arguments
+     *
+     * @return boolean true
+     */
+
+    function isReadOnly($args)
+    {
+        return true;
+    }
+
+    /**
+     * When was this notice last modified?
+     *
+     * @return string datestamp of the latest notice in the stream
+     */
+
+    function lastModified()
+    {
+        if (!empty($this->notice)) {
+            return strtotime($this->notice->created);
+        }
+
+        return null;
+    }
+
+    /**
+     * An entity tag for this notice
+     *
+     * Returns an Etag based on the action name, language, and
+     * timestamps of the notice
+     *
+     * @return string etag
+     */
+
+    function etag()
+    {
+        if (!empty($this->notice)) {
+
+            return '"' . implode(
+                ':',
+                array($this->arg('action'),
+                      common_language(),
+                      $this->notice->id,
+                      strtotime($this->notice->created))
+            )
+            . '"';
+        }
+
+        return null;
+    }
+
+}
diff --git a/actions/apistatusesupdate.php b/actions/apistatusesupdate.php
new file mode 100644 (file)
index 0000000..fb12785
--- /dev/null
@@ -0,0 +1,240 @@
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Post a notice (update your status) through 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/apiauth.php';
+
+/**
+ * Updates the authenticating user's status (posts a notice).
+ *
+ * @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 ApiStatusesUpdateAction extends ApiAuthAction
+{
+
+    var $user                  = null;
+    var $source                = null;
+    var $status                = null;
+    var $in_reply_to_status_id = null;
+    var $format                = null;
+
+    static $reserved_sources = array('web', 'omb', 'mail', 'xmpp', 'api');
+
+    /**
+     * Take arguments for running
+     *
+     * @param array $args $_REQUEST args
+     *
+     * @return boolean success flag
+     *
+     */
+
+    function prepare($args)
+    {
+        parent::prepare($args);
+
+        if ($this->requiresAuth()) {
+            if ($this->checkBasicAuthUser() == false) {
+                return false;
+            }
+        }
+
+        $this->user = $this->auth_user;
+
+        if (empty($this->user)) {
+            $this->clientError(_('No such user!'), 404, $this->format);
+            return false;
+        }
+
+        $this->status = $this->trimmed('status');
+
+        if (empty($this->status)) {
+            $this->clientError(
+                'Client must provide a \'status\' parameter with a value.',
+                400,
+                $this->format
+            );
+
+            return false;
+        }
+
+        $this->source = $this->trimmed('source');
+
+        if (empty($this->source) || in_array($source, $this->reserved_sources)) {
+            $this->source = 'api';
+        }
+
+        $this->format = $this->arg('format');
+
+        $this->in_reply_to_status_id
+            = intval($this->trimmed('in_reply_to_status_id'));
+
+        return true;
+    }
+
+    /**
+     * Handle the request
+     *
+     * Make a new notice for the update, save it, and show it
+     *
+     * @param array $args $_REQUEST data (unused)
+     *
+     * @return void
+     */
+
+    function handle($args)
+    {
+        parent::handle($args);
+
+        if ($_SERVER['REQUEST_METHOD'] != 'POST') {
+            $this->clientError(
+                _('This method requires a POST.'),
+                400, $this->format
+            );
+            return;
+        }
+
+        $status_shortened = common_shorten_links($this->status);
+
+        if (Notice::contentTooLong($status_shortened)) {
+
+            // Note: Twitter truncates anything over 140, flags the status
+            // as "truncated."
+
+            $this->clientError(
+                sprintf(
+                    _('That\'s too long. Max notice size is %d chars.'),
+                    Notice::maxContent()
+                ),
+                406,
+                $this->format
+            );
+
+            return;
+        }
+
+        // Check for commands
+
+        $inter = new CommandInterpreter();
+        $cmd = $inter->handle_command($this->user, $status_shortened);
+
+        if ($cmd) {
+
+            if ($this->supported($cmd)) {
+                $cmd->execute(new Channel());
+            }
+
+            // Cmd not supported?  Twitter just returns your latest status.
+            // And, it returns your last status whether the cmd was successful
+            // or not!
+
+            $this->notice = $this->user->getCurrentNotice();
+
+        } else {
+
+            $reply_to = null;
+
+            if (!empty($this->in_reply_to_status_id)) {
+
+                // Check whether notice actually exists
+
+                $reply = Notice::staticGet($this->in_reply_to_status_id);
+
+                if ($reply) {
+                    $reply_to = $this->in_reply_to_status_id;
+                } else {
+                    $this->clientError(
+                        _('Not found'),
+                        $code = 404,
+                        $this->format
+                    );
+                    return;
+                }
+            }
+
+            $this->notice = Notice::saveNew(
+                $this->user->id,
+                html_entity_decode($this->status, ENT_NOQUOTES, 'UTF-8'),
+                $this->source,
+                1,
+                $reply_to
+            );
+
+            common_broadcast_notice($this->notice);
+        }
+
+        $this->showNotice();
+    }
+
+    /**
+     * Show the resulting notice
+     *
+     * @return void
+     */
+
+    function showNotice()
+    {
+        if (!empty($this->notice)) {
+            if ($this->format == 'xml') {
+                $this->show_single_xml_status($this->notice);
+            } elseif ($this->format == 'json') {
+                $this->show_single_json_status($this->notice);
+            }
+        }
+    }
+
+    /**
+     * Is this command supported when doing an update from the API?
+     *
+     * @param string $cmd the command to check for
+     *
+     * @return boolean true or false
+     */
+
+    function supported($cmd)
+    {
+        static $cmdlist = array('MessageCommand', 'SubCommand', 'UnsubCommand',
+            'FavCommand', 'OnCommand', 'OffCommand');
+
+        if (in_array(get_class($cmd), $cmdlist)) {
+            return true;
+        }
+
+        return false;
+    }
+
+}
diff --git a/actions/apitimelinefriends.php b/actions/apitimelinefriends.php
new file mode 100644 (file)
index 0000000..65bbb5a
--- /dev/null
@@ -0,0 +1,255 @@
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Show the friends timeline
+ *
+ * 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';
+
+/**
+ * Returns the most recent notices (default 20) posted by the target user.
+ * This is the equivalent of 'You and friends' page accessed via Web.
+ *
+ * @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 ApiTimelineFriendsAction extends ApiBareAuthAction
+{
+
+    var $user     = null;
+    var $notices  = null;
+    var $count    = null;
+    var $max_id   = null;
+    var $since_id = null;
+    var $since    = null;
+    var $format   = 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->count    = (int)$this->arg('count', 20);
+        $this->max_id   = (int)$this->arg('max_id', 0);
+        $this->since_id = (int)$this->arg('since_id', 0);
+        $this->since    = $this->arg('since');
+        $this->format   = $this->arg('format');
+
+        if ($this->requiresAuth()) {
+            if ($this->checkBasicAuthUser() == false) {
+                return;
+            }
+        }
+
+        $this->user = $this->getTargetUser($this->arg('id'));
+
+        if (empty($this->user)) {
+            $this->clientError(_('No such user!'), 404, $this->format);
+            return;
+        }
+
+        $this->notices = $this->getNotices();
+
+        return true;
+    }
+
+    /**
+     * Handle the request
+     *
+     * Just show the notices
+     *
+     * @param array $args $_REQUEST data (unused)
+     *
+     * @return void
+     */
+
+    function handle($args)
+    {
+        parent::handle($args);
+        $this->showTimeline();
+    }
+
+    /**
+     * Show the timeline of notices
+     *
+     * @return void
+     */
+
+    function showTimeline()
+    {
+        $profile    = $this->user->getProfile();
+        $sitename   = common_config('site', 'name');
+        $title      = sprintf(_("%s and friends"), $this->user->nickname);
+        $taguribase = common_config('integration', 'taguri');
+        $id         = "tag:$taguribase:FriendsTimeline:" . $this->user->id;
+        $link       = common_local_url(
+            'all', array('nickname' => $this->user->nickname)
+        );
+        $subtitle   = sprintf(
+            _('Updates from %1$s and friends on %2$s!'),
+            $this->user->nickname, $sitename
+        );
+
+        switch($this->format) {
+        case 'xml':
+            $this->show_xml_timeline($this->notices);
+            break;
+        case 'rss':
+            $this->show_rss_timeline($this->notices, $title, $link, $subtitle);
+            break;
+        case 'atom':
+
+            $target_id = $this->arg('id');
+
+            if (isset($target_id)) {
+                $selfuri = common_root_url() .
+                    'api/statuses/friends_timeline/' .
+                    $target_id . '.atom';
+            } else {
+                $selfuri = common_root_url() .
+                    'api/statuses/friends_timeline.atom';
+            }
+
+            $this->show_atom_timeline(
+                $this->notices, $title, $id, $link,
+                $subtitle, null, $selfuri
+            );
+            break;
+        case 'json':
+            $this->show_json_timeline($this->notices);
+            break;
+        default:
+            $this->clientError(_('API method not found!'), $code = 404);
+            break;
+        }
+    }
+
+    /**
+     * Get notices
+     *
+     * @return array notices
+     */
+
+    function getNotices()
+    {
+        $notices = array();
+
+        if (!empty($this->auth_user) && $this->auth_user->id == $this->user->id) {
+            $notice = $this->user->noticeInbox(
+                ($this->page-1) * $this->count,
+                $this->count, $this->since_id,
+                $this->max_id, $this->since
+            );
+        } else {
+            $notice = $this->user->noticesWithFriends(
+                ($this->page-1) * $this->count,
+                $this->count, $this->since_id,
+                $this->max_id, $this->since
+            );
+        }
+
+        while ($notice->fetch()) {
+            $notices[] = clone($notice);
+        }
+
+        return $notices;
+    }
+
+    /**
+     * 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 notice in the stream
+     */
+
+    function lastModified()
+    {
+        if (!empty($this->notices) && (count($this->notices) > 0)) {
+            return strtotime($this->notices[0]->created);
+        }
+
+        return null;
+    }
+
+    /**
+     * An entity tag for this stream
+     *
+     * Returns an Etag based on the action name, language, user ID, and
+     * timestamps of the first and last notice in the timeline
+     *
+     * @return string etag
+     */
+
+    function etag()
+    {
+        if (!empty($this->notices) && (count($this->notices) > 0)) {
+
+            $last = count($this->notices) - 1;
+
+            return '"' . implode(
+                ':',
+                array($this->arg('action'),
+                      common_language(),
+                      $this->user->id,
+                      strtotime($this->notices[0]->created),
+                      strtotime($this->notices[$last]->created))
+            )
+            . '"';
+        }
+
+        return null;
+    }
+
+}
diff --git a/actions/apitimelinementions.php b/actions/apitimelinementions.php
new file mode 100644 (file)
index 0000000..93c6da3
--- /dev/null
@@ -0,0 +1,234 @@
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Show notices mentioning a user (@nickname)
+ *
+ * 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';
+
+/**
+ * Returns the most recent (default 20) mentions (status containing @nickname)
+ *
+ * @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 ApiTimelineMentionsAction extends ApiBareAuthAction
+{
+
+    var $user    = null;
+    var $notices = 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->count    = (int)$this->arg('count', 20);
+        $this->max_id   = (int)$this->arg('max_id', 0);
+        $this->since_id = (int)$this->arg('since_id', 0);
+        $this->since    = $this->arg('since');
+
+        if ($this->requiresAuth()) {
+            if ($this->checkBasicAuthUser() == false) {
+                return;
+            }
+        }
+
+        $this->user = $this->getTargetUser($this->arg('id'));
+
+        if (empty($this->user)) {
+            $this->clientError(_('No such user!'), 404, $this->arg('format'));
+            return;
+        }
+
+        $this->notices = $this->getNotices();
+
+        return true;
+    }
+
+    /**
+     * Handle the request
+     *
+     * Just show the notices
+     *
+     * @param array $args $_REQUEST data (unused)
+     *
+     * @return void
+     */
+
+    function handle($args)
+    {
+        parent::handle($args);
+        $this->showTimeline();
+    }
+
+    /**
+     * Show the timeline of notices
+     *
+     * @return void
+     */
+
+    function showTimeline()
+    {
+        $profile = $this->user->getProfile();
+
+        $sitename   = common_config('site', 'name');
+        $title      = sprintf(
+            _('%1$s / Updates mentioning %2$s'),
+            $sitename, $this->user->nickname
+        );
+        $taguribase = common_config('integration', 'taguri');
+        $id         = "tag:$taguribase:Mentions:" . $this->user->id;
+        $link       = common_local_url(
+            'replies',
+            array('nickname' => $this->user->nickname)
+        );
+        $subtitle   = sprintf(
+            _('%1$s updates that reply to updates from %2$s / %3$s.'),
+            $sitename, $this->user->nickname, $profile->getBestName()
+        );
+
+        switch($this->arg('format')) {
+        case 'xml':
+            $this->show_xml_timeline($this->notices);
+            break;
+        case 'rss':
+            $this->show_rss_timeline($this->notices, $title, $link, $subtitle);
+            break;
+        case 'atom':
+            $selfuri = common_root_url() .
+                ltrim($_SERVER['QUERY_STRING'], 'p=');
+            $this->show_atom_timeline(
+                $this->notices, $title, $id, $link, $subtitle,
+                null, $selfuri
+            );
+            break;
+        case 'json':
+            $this->show_json_timeline($this->notices);
+            break;
+        default:
+            $this->clientError(_('API method not found!'), $code = 404);
+            break;
+        }
+    }
+
+    /**
+     * Get notices
+     *
+     * @return array notices
+     */
+
+    function getNotices()
+    {
+        $notices = array();
+
+        $notice = $this->user->getReplies(
+            ($this->page - 1) * $this->count, $this->count,
+            $this->since_id, $this->max_id, $this->since
+        );
+
+        while ($notice->fetch()) {
+            $notices[] = clone($notice);
+        }
+
+        return $notices;
+    }
+
+    /**
+     * 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 notice in the stream
+     */
+
+    function lastModified()
+    {
+        if (!empty($this->notices) && (count($this->notices) > 0)) {
+            return strtotime($this->notices[0]->created);
+        }
+
+        return null;
+    }
+
+    /**
+     * An entity tag for this stream
+     *
+     * Returns an Etag based on the action name, language, user ID, and
+     * timestamps of the first and last notice in the timeline
+     *
+     * @return string etag
+     */
+
+    function etag()
+    {
+        if (!empty($this->notices) && (count($this->notices) > 0)) {
+
+            $last = count($this->notices) - 1;
+
+            return '"' . implode(
+                ':',
+                array($this->arg('action'),
+                      common_language(),
+                      $this->user->id,
+                      strtotime($this->notices[0]->created),
+                      strtotime($this->notices[$last]->created))
+            )
+            . '"';
+        }
+
+        return null;
+    }
+
+}
diff --git a/actions/apitimelinepublic.php b/actions/apitimelinepublic.php
new file mode 100644 (file)
index 0000000..10bde6f
--- /dev/null
@@ -0,0 +1,207 @@
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Show the public timeline
+ *
+ * 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/twitterapi.php';
+
+/**
+ * Returns the most recent notices (default 20) posted by everybody
+ *
+ * @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 ApiTimelinePublicAction extends TwitterapiAction
+{
+
+    var $notices = 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->count    = (int)$this->arg('count', 20);
+        $this->max_id   = (int)$this->arg('max_id', 0);
+        $this->since_id = (int)$this->arg('since_id', 0);
+        $this->since    = $this->arg('since');
+
+        $this->notices = $this->getNotices();
+
+        return true;
+    }
+
+    /**
+     * Handle the request
+     *
+     * Just show the notices
+     *
+     * @param array $args $_REQUEST data (unused)
+     *
+     * @return void
+     */
+
+    function handle($args)
+    {
+        parent::handle($args);
+        $this->showTimeline();
+    }
+
+    /**
+     * Show the timeline of notices
+     *
+     * @return void
+     */
+
+    function showTimeline()
+    {
+        $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);
+
+        switch($this->arg('format')) {
+        case 'xml':
+            $this->show_xml_timeline($this->notices);
+            break;
+        case 'rss':
+            $this->show_rss_timeline($this->notices, $title, $link, $subtitle);
+            break;
+        case 'atom':
+            $selfuri = common_root_url() . 'api/statuses/public_timeline.atom';
+            $this->show_atom_timeline(
+                $this->notices, $title, $id, $link,
+                $subtitle, null, $selfuri
+            );
+            break;
+        case 'json':
+            $this->show_json_timeline($this->notices);
+            break;
+        default:
+            $this->clientError(_('API method not found!'), $code = 404);
+            break;
+        }
+    }
+
+    /**
+     * Get notices
+     *
+     * @return array notices
+     */
+
+    function getNotices()
+    {
+        $notices = array();
+
+        $notice = Notice::publicStream(
+            ($this->page - 1) * $this->count, $this->count, $this->since_id,
+            $this->max_id, $this->since
+        );
+
+        while ($notice->fetch()) {
+            $notices[] = clone($notice);
+        }
+
+        return $notices;
+    }
+
+    /**
+     * 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 notice in the stream
+     */
+
+    function lastModified()
+    {
+        if (!empty($this->notices) && (count($this->notices) > 0)) {
+            return strtotime($this->notices[0]->created);
+        }
+
+        return null;
+    }
+
+    /**
+     * An entity tag for this stream
+     *
+     * Returns an Etag based on the action name, language, and
+     * timestamps of the first and last notice in the timeline
+     *
+     * @return string etag
+     */
+
+    function etag()
+    {
+        if (!empty($this->notices) && (count($this->notices) > 0)) {
+
+            $last = count($this->notices) - 1;
+
+            return '"' . implode(
+                ':',
+                array($this->arg('action'),
+                      common_language(),
+                      strtotime($this->notices[0]->created),
+                      strtotime($this->notices[$last]->created))
+            )
+            . '"';
+        }
+
+        return null;
+    }
+
+}
diff --git a/actions/apitimelineuser.php b/actions/apitimelineuser.php
new file mode 100644 (file)
index 0000000..c4d02bc
--- /dev/null
@@ -0,0 +1,249 @@
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Show a user's timeline
+ *
+ * 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';
+
+/**
+ * Returns the most recent notices (default 20) posted by the authenticating
+ * user. Another user's timeline can be requested via the id parameter. This
+ * is the API equivalent of the user profile web page.
+ *
+ * @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 ApiTimelineUserAction extends ApiBareAuthAction
+{
+
+    var $user    = null;
+    var $notices = 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->count    = (int)$this->arg('count', 20);
+        $this->max_id   = (int)$this->arg('max_id', 0);
+        $this->since_id = (int)$this->arg('since_id', 0);
+        $this->since    = $this->arg('since');
+
+        if ($this->requiresAuth()) {
+            if ($this->checkBasicAuthUser() == false) {
+                return;
+            }
+        }
+
+        $this->user = $this->getTargetUser($this->arg('id'));
+
+        if (empty($this->user)) {
+            $this->clientError(_('No such user!'), 404, $this->arg('format'));
+            return;
+        }
+
+        $this->notices = $this->getNotices();
+
+        return true;
+    }
+
+    /**
+     * Handle the request
+     *
+     * Just show the notices
+     *
+     * @param array $args $_REQUEST data (unused)
+     *
+     * @return void
+     */
+
+    function handle($args)
+    {
+        parent::handle($args);
+        $this->showTimeline();
+    }
+
+    /**
+     * Show the timeline of notices
+     *
+     * @return void
+     */
+
+    function showTimeline()
+    {
+        $profile = $this->user->getProfile();
+
+        $sitename   = common_config('site', 'name');
+        $title      = sprintf(_("%s timeline"), $this->user->nickname);
+        $taguribase = common_config('integration', 'taguri');
+        $id         = "tag:$taguribase:UserTimeline:" . $this->user->id;
+        $link       = common_local_url(
+            'showstream',
+            array('nickname' => $this->user->nickname)
+        );
+        $subtitle   = sprintf(
+            _('Updates from %1$s on %2$s!'),
+            $this->user->nickname, $sitename
+        );
+
+        // FriendFeed's SUP protocol
+        // Also added RSS and Atom feeds
+
+        $suplink = common_local_url('sup', null, null, $this->user->id);
+        header('X-SUP-ID: ' . $suplink);
+
+        switch($this->arg('format')) {
+        case 'xml':
+            $this->show_xml_timeline($this->notices);
+            break;
+        case 'rss':
+            $this->show_rss_timeline(
+                $this->notices, $title, $link,
+                $subtitle, $suplink
+            );
+            break;
+        case 'atom':
+            if (isset($apidata['api_arg'])) {
+                $selfuri = common_root_url() .
+                    'api/statuses/user_timeline/' .
+                    $apidata['api_arg'] . '.atom';
+            } else {
+                $selfuri = common_root_url() .
+                    'api/statuses/user_timeline.atom';
+            }
+            $this->show_atom_timeline(
+                $this->notices, $title, $id, $link,
+                $subtitle, $suplink, $selfuri
+            );
+            break;
+        case 'json':
+            $this->show_json_timeline($this->notices);
+            break;
+        default:
+            $this->clientError(_('API method not found!'), $code = 404);
+            break;
+        }
+
+    }
+
+    /**
+     * Get notices
+     *
+     * @return array notices
+     */
+
+    function getNotices()
+    {
+        $notices = array();
+
+        $notice = $this->user->getNotices(
+            ($this->page-1) * $this->count, $this->count,
+            $this->since_id, $this->max_id, $this->since
+        );
+
+        while ($notice->fetch()) {
+            $notices[] = clone($notice);
+        }
+
+        return $notices;
+    }
+
+    /**
+     * 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 notice in the stream
+     */
+
+    function lastModified()
+    {
+        if (!empty($this->notices) && (count($this->notices) > 0)) {
+            return strtotime($this->notices[0]->created);
+        }
+
+        return null;
+    }
+
+    /**
+     * An entity tag for this stream
+     *
+     * Returns an Etag based on the action name, language, user ID, and
+     * timestamps of the first and last notice in the timeline
+     *
+     * @return string etag
+     */
+
+    function etag()
+    {
+        if (!empty($this->notices) && (count($this->notices) > 0)) {
+
+            $last = count($this->notices) - 1;
+
+            return '"' . implode(
+                ':',
+                array($this->arg('action'),
+                      common_language(),
+                      $this->user->id,
+                      strtotime($this->notices[0]->created),
+                      strtotime($this->notices[$last]->created))
+            )
+            . '"';
+        }
+
+        return null;
+    }
+
+}
diff --git a/actions/apiupdate.php b/actions/apiupdate.php
deleted file mode 100644 (file)
index 04a38f3..0000000
+++ /dev/null
@@ -1,240 +0,0 @@
-<?php
-/**
- * StatusNet, the distributed open-source microblogging tool
- *
- * Post a notice (update your status) through 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/apiauth.php';
-
-/**
- * Updates the authenticating user's status (posts a notice).
- *
- * @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 ApiUpdateAction extends ApiAuthAction
-{
-
-    var $user                  = null;
-    var $source                = null;
-    var $status                = null;
-    var $in_reply_to_status_id = null;
-    var $format                = null;
-
-    static $reserved_sources = array('web', 'omb', 'mail', 'xmpp', 'api');
-
-    /**
-     * Take arguments for running
-     *
-     * @param array $args $_REQUEST args
-     *
-     * @return boolean success flag
-     *
-     */
-
-    function prepare($args)
-    {
-        parent::prepare($args);
-
-        if ($this->requiresAuth()) {
-            if ($this->checkBasicAuthUser() == false) {
-                return false;
-            }
-        }
-
-        $this->user = $this->auth_user;
-
-        if (empty($this->user)) {
-            $this->clientError(_('No such user!'), 404, $this->format);
-            return false;
-        }
-
-        $this->status = $this->trimmed('status');
-
-        if (empty($this->status)) {
-            $this->clientError(
-                'Client must provide a \'status\' parameter with a value.',
-                400,
-                $this->format
-            );
-
-            return false;
-        }
-
-        $this->source = $this->trimmed('source');
-
-        if (empty($this->source) || in_array($source, $this->reserved_sources)) {
-            $this->source = 'api';
-        }
-
-        $this->format = $this->arg('format');
-
-        $this->in_reply_to_status_id
-            = intval($this->trimmed('in_reply_to_status_id'));
-
-        return true;
-    }
-
-    /**
-     * Handle the request
-     *
-     * Make a new notice for the update, save it, and show it
-     *
-     * @param array $args $_REQUEST data (unused)
-     *
-     * @return void
-     */
-
-    function handle($args)
-    {
-        parent::handle($args);
-
-        if ($_SERVER['REQUEST_METHOD'] != 'POST') {
-            $this->clientError(
-                _('This method requires a POST.'),
-                400, $this->format
-            );
-            return;
-        }
-
-        $status_shortened = common_shorten_links($this->status);
-
-        if (Notice::contentTooLong($status_shortened)) {
-
-            // Note: Twitter truncates anything over 140, flags the status
-            // as "truncated."
-
-            $this->clientError(
-                sprintf(
-                    _('That\'s too long. Max notice size is %d chars.'),
-                    Notice::maxContent()
-                ),
-                406,
-                $this->format
-            );
-
-            return;
-        }
-
-        // Check for commands
-
-        $inter = new CommandInterpreter();
-        $cmd = $inter->handle_command($this->user, $status_shortened);
-
-        if ($cmd) {
-
-            if ($this->supported($cmd)) {
-                $cmd->execute(new Channel());
-            }
-
-            // Cmd not supported?  Twitter just returns your latest status.
-            // And, it returns your last status whether the cmd was successful
-            // or not!
-
-            $this->notice = $this->user->getCurrentNotice();
-
-        } else {
-
-            $reply_to = null;
-
-            if (!empty($this->in_reply_to_status_id)) {
-
-                // Check whether notice actually exists
-
-                $reply = Notice::staticGet($this->in_reply_to_status_id);
-
-                if ($reply) {
-                    $reply_to = $this->in_reply_to_status_id;
-                } else {
-                    $this->clientError(
-                        _('Not found'),
-                        $code = 404,
-                        $this->format
-                    );
-                    return;
-                }
-            }
-
-            $this->notice = Notice::saveNew(
-                $this->user->id,
-                html_entity_decode($this->status, ENT_NOQUOTES, 'UTF-8'),
-                $this->source,
-                1,
-                $reply_to
-            );
-
-            common_broadcast_notice($this->notice);
-        }
-
-        $this->showNotice();
-    }
-
-    /**
-     * Show the resulting notice
-     *
-     * @return void
-     */
-
-    function showNotice()
-    {
-        if (!empty($this->notice)) {
-            if ($this->format == 'xml') {
-                $this->show_single_xml_status($this->notice);
-            } elseif ($this->format == 'json') {
-                $this->show_single_json_status($this->notice);
-            }
-        }
-    }
-
-    /**
-     * Is this command supported when doing an update from the API?
-     *
-     * @param string $cmd the command to check for
-     *
-     * @return boolean true or false
-     */
-
-    function supported($cmd)
-    {
-        static $cmdlist = array('MessageCommand', 'SubCommand', 'UnsubCommand',
-            'FavCommand', 'OnCommand', 'OffCommand');
-
-        if (in_array(get_class($cmd), $cmdlist)) {
-            return true;
-        }
-
-        return false;
-    }
-
-}
diff --git a/actions/apiuserfollowers.php b/actions/apiuserfollowers.php
new file mode 100644 (file)
index 0000000..5c02434
--- /dev/null
@@ -0,0 +1,85 @@
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Show a user's followers (subscribers)
+ *
+ * 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 ApiUserFollowersAction 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/apiuserfriends.php b/actions/apiuserfriends.php
new file mode 100644 (file)
index 0000000..8a42e36
--- /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 ApiUserFriendsAction 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/apiusertimeline.php b/actions/apiusertimeline.php
deleted file mode 100644 (file)
index 44d6941..0000000
+++ /dev/null
@@ -1,249 +0,0 @@
-<?php
-/**
- * StatusNet, the distributed open-source microblogging tool
- *
- * Show a user's timeline
- *
- * 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';
-
-/**
- * Returns the most recent notices (default 20) posted by the authenticating
- * user. Another user's timeline can be requested via the id parameter. This
- * is the API equivalent of the user profile web page.
- *
- * @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 ApiUserTimelineAction extends ApiBareAuthAction
-{
-
-    var $user    = null;
-    var $notices = 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->count    = (int)$this->arg('count', 20);
-        $this->max_id   = (int)$this->arg('max_id', 0);
-        $this->since_id = (int)$this->arg('since_id', 0);
-        $this->since    = $this->arg('since');
-
-        if ($this->requiresAuth()) {
-            if ($this->checkBasicAuthUser() == false) {
-                return;
-            }
-        }
-
-        $this->user = $this->getTargetUser($this->arg('id'));
-
-        if (empty($this->user)) {
-            $this->clientError(_('No such user!'), 404, $this->arg('format'));
-            return;
-        }
-
-        $this->notices = $this->getNotices();
-
-        return true;
-    }
-
-    /**
-     * Handle the request
-     *
-     * Just show the notices
-     *
-     * @param array $args $_REQUEST data (unused)
-     *
-     * @return void
-     */
-
-    function handle($args)
-    {
-        parent::handle($args);
-        $this->showTimeline();
-    }
-
-    /**
-     * Show the timeline of notices
-     *
-     * @return void
-     */
-
-    function showTimeline()
-    {
-        $profile = $this->user->getProfile();
-
-        $sitename   = common_config('site', 'name');
-        $title      = sprintf(_("%s timeline"), $this->user->nickname);
-        $taguribase = common_config('integration', 'taguri');
-        $id         = "tag:$taguribase:UserTimeline:" . $this->user->id;
-        $link       = common_local_url(
-            'showstream',
-            array('nickname' => $this->user->nickname)
-        );
-        $subtitle   = sprintf(
-            _('Updates from %1$s on %2$s!'),
-            $this->user->nickname, $sitename
-        );
-
-        // FriendFeed's SUP protocol
-        // Also added RSS and Atom feeds
-
-        $suplink = common_local_url('sup', null, null, $this->user->id);
-        header('X-SUP-ID: ' . $suplink);
-
-        switch($this->arg('format')) {
-        case 'xml':
-            $this->show_xml_timeline($this->notices);
-            break;
-        case 'rss':
-            $this->show_rss_timeline(
-                $this->notices, $title, $link,
-                $subtitle, $suplink
-            );
-            break;
-        case 'atom':
-            if (isset($apidata['api_arg'])) {
-                $selfuri = common_root_url() .
-                    'api/statuses/user_timeline/' .
-                    $apidata['api_arg'] . '.atom';
-            } else {
-                $selfuri = common_root_url() .
-                    'api/statuses/user_timeline.atom';
-            }
-            $this->show_atom_timeline(
-                $this->notices, $title, $id, $link,
-                $subtitle, $suplink, $selfuri
-            );
-            break;
-        case 'json':
-            $this->show_json_timeline($this->notices);
-            break;
-        default:
-            $this->clientError(_('API method not found!'), $code = 404);
-            break;
-        }
-
-    }
-
-    /**
-     * Get notices
-     *
-     * @return array notices
-     */
-
-    function getNotices()
-    {
-        $notices = array();
-
-        $notice = $this->user->getNotices(
-            ($this->page-1) * $this->count, $this->count,
-            $this->since_id, $this->max_id, $this->since
-        );
-
-        while ($notice->fetch()) {
-            $notices[] = clone($notice);
-        }
-
-        return $notices;
-    }
-
-    /**
-     * 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 notice in the stream
-     */
-
-    function lastModified()
-    {
-        if (!empty($this->notices) && (count($this->notices) > 0)) {
-            return strtotime($this->notices[0]->created);
-        }
-
-        return null;
-    }
-
-    /**
-     * An entity tag for this stream
-     *
-     * Returns an Etag based on the action name, language, user ID, and
-     * timestamps of the first and last notice in the timeline
-     *
-     * @return string etag
-     */
-
-    function etag()
-    {
-        if (!empty($this->notices) && (count($this->notices) > 0)) {
-
-            $last = count($this->notices) - 1;
-
-            return '"' . implode(
-                ':',
-                array($this->arg('action'),
-                      common_language(),
-                      $this->user->id,
-                      strtotime($this->notices[0]->created),
-                      strtotime($this->notices[$last]->created))
-            )
-            . '"';
-        }
-
-        return null;
-    }
-
-}
diff --git a/actions/twitapistatuses.php b/actions/twitapistatuses.php
deleted file mode 100644 (file)
index 87043b1..0000000
+++ /dev/null
@@ -1,606 +0,0 @@
-<?php
-/*
- * StatusNet - the distributed open-source microblogging tool
- * Copyright (C) 2008, 2009, StatusNet, Inc.
- *
- * 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/>.
- */
-
-if (!defined('STATUSNET') && !defined('LACONICA')) {
-    exit(1);
-}
-
-require_once(INSTALLDIR.'/lib/twitterapi.php');
-
-class TwitapistatusesAction extends TwitterapiAction
-{
-
-    function public_timeline($args, $apidata)
-    {
-        // 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
-
-        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);
-
-        $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 = 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;
-        }
-
-    }
-
-    function friends_timeline($args, $apidata)
-    {
-        parent::handle($args);
-
-        $this->auth_user = $apidata['user'];
-        $user = $this->get_user($apidata['api_arg'], $apidata);
-
-        if (empty($user)) {
-             $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);
-        $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);
-
-        $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 (!empty($this->auth_user) && $this->auth_user->id == $user->id) {
-            $notice = $user->noticeInbox(($page-1)*$count,
-                $count, $since_id, $max_id, $since);
-        } else {
-            $notice = $user->noticesWithFriends(($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':
-            if (isset($apidata['api_arg'])) {
-                $selfuri = common_root_url() .
-                    '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);
-            break;
-        case 'json':
-            $this->show_json_timeline($notice);
-            break;
-        default:
-            $this->clientError(_('API method not found!'), $code = 404);
-        }
-
-    }
-
-    function home_timeline($args, $apidata)
-    {
-        call_user_func(array($this, 'friends_timeline'), $args, $apidata);
-    }
-
-    function user_timeline($args, $apidata)
-    {
-        parent::handle($args);
-
-        $this->auth_user = $apidata['user'];
-        $user = $this->get_user($apidata['api_arg'], $apidata);
-
-        if (empty($user)) {
-            $this->clientError('Not Found', 404, $apidata['content-type']);
-            return;
-        }
-
-        $profile = $user->getProfile();
-
-        $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);
-
-        # FriendFeed's SUP protocol
-        # Also added RSS and Atom feeds
-
-        $suplink = common_local_url('sup', null, null, $user->id);
-        header('X-SUP-ID: '.$suplink);
-
-        $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)*$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);
-            break;
-         case 'atom':
-            if (isset($apidata['api_arg'])) {
-                $selfuri = common_root_url() .
-                    '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);
-            break;
-         case 'json':
-            $this->show_json_timeline($notice);
-            break;
-         default:
-            $this->clientError(_('API method not found!'), $code = 404);
-        }
-
-    }
-
-    function update($args, $apidata)
-    {
-        parent::handle($args);
-
-        if (!in_array($apidata['content-type'], array('xml', 'json'))) {
-            $this->clientError(_('API method not found!'), $code = 404);
-            return;
-        }
-
-        if ($_SERVER['REQUEST_METHOD'] != 'POST') {
-            $this->clientError(_('This method requires a POST.'),
-                400, $apidata['content-type']);
-            return;
-        }
-
-        $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'));
-        $reserved_sources = array('web', 'omb', 'mail', 'xmpp', 'api');
-
-        if (empty($source) || in_array($source, $reserved_sources)) {
-            $source = 'api';
-        }
-
-        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
-            // user's timeline.     Seems bad.     Shouldn't we throw an
-            // errror? -- Zach
-            return;
-
-        } else {
-
-            $status_shortened = common_shorten_links($status);
-
-            if (Notice::contentTooLong($status_shortened)) {
-
-                // XXX: Twitter truncates anything over 140, flags the status
-                // 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(sprintf(_('That\'s too long. Max notice size is %d chars.'),
-                                           Notice::maxContent()),
-                                   $code = 406, $apidata['content-type']);
-                return;
-            }
-        }
-
-        // Check for commands
-        $inter = new CommandInterpreter();
-        $cmd = $inter->handle_command($user, $status_shortened);
-
-        if ($cmd) {
-
-            if ($this->supported($cmd)) {
-                $cmd->execute(new Channel());
-            }
-
-            // cmd not supported?  Twitter just returns your latest status.
-            // And, it returns your last status whether the cmd was successful
-            // or not!
-            $n = $user->getCurrentNotice();
-            $apidata['api_arg'] = $n->id;
-        } else {
-
-            $reply_to = null;
-
-            if ($in_reply_to_status_id) {
-
-                // check whether notice actually exists
-                $reply = Notice::staticGet($in_reply_to_status_id);
-
-                if ($reply) {
-                    $reply_to = $in_reply_to_status_id;
-                } else {
-                    $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);
-
-            common_broadcast_notice($notice);
-            $apidata['api_arg'] = $notice->id;
-        }
-
-        $this->show($args, $apidata);
-    }
-
-    function mentions($args, $apidata)
-    {
-        parent::handle($args);
-
-        $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, $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.'),
-            $sitename, $user->nickname, $profile->getBestName());
-
-        $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->getReplies(($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() .
-                ltrim($_SERVER['QUERY_STRING'], 'p=');
-            $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);
-        }
-
-    }
-
-    function replies($args, $apidata)
-    {
-        call_user_func(array($this, 'mentions'), $args, $apidata);
-    }
-
-    function show($args, $apidata)
-    {
-        parent::handle($args);
-
-        if (!in_array($apidata['content-type'], array('xml', 'json'))) {
-            $this->clientError(_('API method not found!'), $code = 404);
-            return;
-        }
-
-        // 'id' is an undocumented parameter in Twitter's API. Several
-        // clients make use of it, so we support it too.
-
-        // show.json?id=12345 takes precedence over /show/12345.json
-
-        $this->auth_user = $apidata['user'];
-        $notice_id       = $this->trimmed('id');
-
-        if (empty($notice_id)) {
-            $notice_id   = $apidata['api_arg'];
-        }
-
-        $notice          = Notice::staticGet((int)$notice_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 {
-            // XXX: Twitter just sets a 404 header and doens't bother
-            // to return an err msg
-            $deleted = Deleted_notice::staticGet($notice_id);
-            if (!empty($deleted)) {
-                $this->clientError(_('Status deleted.'),
-                                   410, $apidata['content-type']);
-            } else {
-                $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'))) {
-            $this->clientError(_('API method not found!'), $code = 404);
-            return;
-        }
-
-        // 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']);
-            return;
-        }
-
-        $user      = $apidata['user']; // Always the auth user
-        $notice_id = $apidata['api_arg'];
-        $notice    = Notice::staticGet($notice_id);
-
-        if (empty($notice)) {
-            $this->clientError(_('No status found with that ID.'),
-                404, $apidata['content-type']);
-            return;
-        }
-
-        if ($user->id == $notice->profile_id) {
-            $replies = new Reply;
-            $replies->get('notice_id', $notice_id);
-            $replies->delete();
-            $notice->delete();
-
-            if ($apidata['content-type'] == 'xml') {
-                $this->show_single_xml_status($notice);
-            } elseif ($apidata['content-type'] == 'json') {
-                $this->show_single_json_status($notice);
-            }
-        } else {
-            $this->clientError(_('You may not delete another user\'s status.'),
-                403, $apidata['content-type']);
-        }
-
-    }
-
-    function friends($args, $apidata)
-    {
-        parent::handle($args);
-        $includeStatuses=! (boolean) $args['lite'];
-        return $this->subscriptions($apidata, 'subscribed', 'subscriber', false, $includeStatuses);
-    }
-
-    function friendsIDs($args, $apidata)
-    {
-        parent::handle($args);
-        return $this->subscriptions($apidata, 'subscribed', 'subscriber', true);
-    }
-
-    function followers($args, $apidata)
-    {
-        parent::handle($args);
-        $includeStatuses=! (boolean) $args['lite'];
-        return $this->subscriptions($apidata, 'subscriber', 'subscribed', false, $includeStatuses);
-    }
-
-    function followersIDs($args, $apidata)
-    {
-        parent::handle($args);
-        return $this->subscriptions($apidata, 'subscriber', 'subscribed', true);
-    }
-
-    function subscriptions($apidata, $other_attr, $user_attr, $onlyIDs=false, $includeStatuses=true)
-    {
-        $this->auth_user = $apidata['user'];
-        $user = $this->get_user($apidata['api_arg'], $apidata);
-
-        if (empty($user)) {
-            $this->clientError('Not Found', 404, $apidata['content-type']);
-            return;
-        }
-
-        $profile = $user->getProfile();
-
-        $sub = new Subscription();
-        $sub->$user_attr = $profile->id;
-
-        $sub->orderBy('created DESC');
-
-        // Normally, page 100 friends at a time
-
-        if (!$onlyIDs) {
-            $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();
-
-        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);
-
-        if ($onlyIDs) {
-            $this->showIDs($others, $type);
-        } else {
-            $this->show_profiles($others, $type, $includeStatuses);
-        }
-
-        $this->end_document($type);
-    }
-
-    function show_profiles($profiles, $type, $includeStatuses)
-    {
-        switch ($type) {
-        case 'xml':
-            $this->elementStart('users', array('type' => 'array'));
-            foreach ($profiles as $profile) {
-                $this->show_profile($profile,$type,null,$includeStatuses);
-            }
-            $this->elementEnd('users');
-            break;
-        case 'json':
-            $arrays = array();
-            foreach ($profiles as $profile) {
-                $arrays[] = $this->twitter_user_array($profile, $includeStatuses);
-            }
-            print json_encode($arrays);
-            break;
-        default:
-            $this->clientError(_('unsupported file type'));
-        }
-    }
-
-    function showIDs($profiles, $type)
-    {
-        switch ($type) {
-        case 'xml':
-            $this->elementStart('ids');
-            foreach ($profiles as $profile) {
-                $this->element('id', null, $profile->id);
-            }
-            $this->elementEnd('ids');
-            break;
-        case 'json':
-            $ids = array();
-            foreach ($profiles as $profile) {
-                $ids[] = (int)$profile->id;
-            }
-            print json_encode($ids);
-            break;
-        default:
-            $this->clientError(_('unsupported file type'));
-        }
-    }
-
-    function featured($args, $apidata)
-    {
-        parent::handle($args);
-        $this->serverError(_('API method under construction.'), $code=501);
-    }
-
-    function supported($cmd)
-    {
-        $cmdlist = array('MessageCommand', 'SubCommand', 'UnsubCommand',
-            'FavCommand', 'OnCommand', 'OffCommand');
-
-        if (in_array(get_class($cmd), $cmdlist)) {
-            return true;
-        }
-
-        return false;
-    }
-
-}
index 5c9513f570a8a1569a216997ed82d4df663403de..357c7022477ba989964a4873e747be2be7ea16fa 100644 (file)
@@ -271,90 +271,90 @@ class Router
         // statuses API
 
         $m->connect('api/statuses/public_timeline.:format',
-                    array('action' => 'ApiPublicTimeline',
+                    array('action' => 'ApiTimelinePublic',
                     'format' => '(xml|json|rss|atom)'));
 
         $m->connect('api/statuses/friends_timeline.:format',
-                    array('action' => 'ApiFriendsTimeline',
+                    array('action' => 'ApiTimelineFriends',
                           'format' => '(xml|json|rss|atom)'));
 
         $m->connect('api/statuses/friends_timeline/:id.:format',
-                    array('action' => 'ApiFriendsTimeline',
+                    array('action' => 'ApiTimelineFriends',
                           'id' => '[a-zA-Z0-9]+',
                           'format' => '(xml|json|rss|atom)'));
         $m->connect('api/statuses/home_timeline.:format',
-                    array('action' => 'ApiFriendsTimeline',
+                    array('action' => 'ApiTimelineFriends',
                           'format' => '(xml|json|rss|atom)'));
 
         $m->connect('api/statuses/home_timeline/:id.:format',
-                    array('action' => 'ApiFriendsTimeline',
+                    array('action' => 'ApiTimelineFriends',
                           'id' => '[a-zA-Z0-9]+',
                           'format' => '(xml|json|rss|atom)'));
 
         $m->connect('api/statuses/user_timeline.:format',
-                    array('action' => 'ApiUserTimeline',
+                    array('action' => 'ApiTimelineUser',
                     'format' => '(xml|json|rss|atom)'));
 
         $m->connect('api/statuses/user_timeline/:id.:format',
-                    array('action' => 'ApiUserTimeline',
+                    array('action' => 'ApiTimelineUser',
                     'id' => '[a-zA-Z0-9]+',
                     'format' => '(xml|json|rss|atom)'));
 
         $m->connect('api/statuses/mentions.:format',
-                    array('action' => 'ApiMentions',
+                    array('action' => 'ApiTimelineMentions',
                     'format' => '(xml|json|rss|atom)'));
 
         $m->connect('api/statuses/mentions/:id.:format',
-                    array('action' => 'ApiMentions',
+                    array('action' => 'ApiTimelineMentions',
                     'id' => '[a-zA-Z0-9]+',
                     'format' => '(xml|json|rss|atom)'));
 
         $m->connect('api/statuses/replies.:format',
-                    array('action' => 'ApiMentions',
+                    array('action' => 'ApiTimelineMentions',
                     'format' => '(xml|json|rss|atom)'));
 
         $m->connect('api/statuses/replies/:id.:format',
-                    array('action' => 'ApiMentions',
+                    array('action' => 'ApiTimelineMentions',
                     'id' => '[a-zA-Z0-9]+',
                     'format' => '(xml|json|rss|atom)'));
 
         $m->connect('api/statuses/friends.:format',
-                     array('action' => 'ApiFriends',
+                     array('action' => 'ApiUserFriends',
                            'format' => '(xml|json)'));
 
         $m->connect('api/statuses/friends/:id.:format',
-                    array('action' => 'ApiFriends',
+                    array('action' => 'ApiUserFriends',
                     'id' => '[a-zA-Z0-9]+',
                     'format' => '(xml|json)'));
 
         $m->connect('api/statuses/followers.:format',
-                     array('action' => 'ApiFollowers',
+                     array('action' => 'ApiUserFollowers',
                            'format' => '(xml|json)'));
 
         $m->connect('api/statuses/followers/:id.:format',
-                    array('action' => 'ApiFollowers',
+                    array('action' => 'ApiUserFollowers',
                     'id' => '[a-zA-Z0-9]+',
                     'format' => '(xml|json)'));
 
         $m->connect('api/statuses/show.:format',
-                    array('action' => 'ApiShow',
+                    array('action' => 'ApiStatusesShow',
                           'format' => '(xml|json)'));
 
         $m->connect('api/statuses/show/:id.:format',
-                    array('action' => 'ApiShow',
+                    array('action' => 'ApiStatusesShow',
                           'id' => '[0-9]+',
                           'format' => '(xml|json)'));
 
         $m->connect('api/statuses/update.:format',
-                    array('action' => 'ApiUpdate',
+                    array('action' => 'ApiStatusesUpdate',
                           'format' => '(xml|json)'));
 
         $m->connect('api/statuses/destroy.:format',
-                  array('action' => 'ApiDestroy',
+                  array('action' => 'ApiStatusesDestroy',
                         'format' => '(xml|json)'));
 
         $m->connect('api/statuses/destroy/:id.:format',
-                  array('action' => 'ApiDestroy',
+                  array('action' => 'ApiStatusesDestroy',
                         'id' => '[0-9]+',
                         'format' => '(xml|json)'));