forked from GNUsocial/gnu-social
Merge branch '0.9.x' of git@gitorious.org:statusnet/mainline into 0.9.x-mobile
This commit is contained in:
commit
861e0f0227
306
actions/api.php
306
actions/api.php
@ -1,306 +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/>.
|
|
||||||
*
|
|
||||||
* @category Actions
|
|
||||||
* @package Actions
|
|
||||||
* @author Evan Prodromou <evan@status.net>
|
|
||||||
* @author Brenda Wallace <shiny@cpan.org>
|
|
||||||
* @author Jeffery To <jeffery.to@gmail.com>
|
|
||||||
* @author Robin Millette <millette@controlyourself.ca>
|
|
||||||
* @author Tom Adams <tom@holizz.com>
|
|
||||||
* @author Christopher Vollick <psycotica0@gmail.com>
|
|
||||||
* @author CiaranG <ciaran@ciarang.com>
|
|
||||||
* @author Craig Andrews <candrews@integralblue.com>
|
|
||||||
* @author Gina Haeussge <osd@foosel.net>
|
|
||||||
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
|
||||||
* @author Sarven Capadisli <csarven@status.net>
|
|
||||||
* @license GNU Affero General Public License http://www.gnu.org/licenses/
|
|
||||||
* @link http://status.net
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
class ApiAction extends Action
|
|
||||||
{
|
|
||||||
|
|
||||||
var $user;
|
|
||||||
var $content_type;
|
|
||||||
var $api_arg;
|
|
||||||
var $api_method;
|
|
||||||
var $api_action;
|
|
||||||
var $auth_user;
|
|
||||||
var $auth_pw;
|
|
||||||
|
|
||||||
function handle($args)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
|
|
||||||
$this->api_action = $this->arg('apiaction');
|
|
||||||
$method = $this->arg('method');
|
|
||||||
$argument = $this->arg('argument');
|
|
||||||
$this->basic_auth_process_header();
|
|
||||||
|
|
||||||
if (isset($argument)) {
|
|
||||||
$cmdext = explode('.', $argument);
|
|
||||||
$this->api_arg = $cmdext[0];
|
|
||||||
$this->api_method = $method;
|
|
||||||
$this->content_type = strtolower($cmdext[1]);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
//Requested format / content-type will be an extension on the method
|
|
||||||
$cmdext = explode('.', $method);
|
|
||||||
$this->api_method = $cmdext[0];
|
|
||||||
$this->content_type = strtolower($cmdext[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->requires_auth()) {
|
|
||||||
if (!isset($this->auth_user)) {
|
|
||||||
|
|
||||||
//This header makes basic auth go
|
|
||||||
header('WWW-Authenticate: Basic realm="StatusNet API"');
|
|
||||||
|
|
||||||
//If the user hits cancel -- bam!
|
|
||||||
$this->show_basic_auth_error();
|
|
||||||
} else {
|
|
||||||
$nickname = $this->auth_user;
|
|
||||||
$password = $this->auth_pw;
|
|
||||||
$user = common_check_user($nickname, $password);
|
|
||||||
|
|
||||||
if ($user) {
|
|
||||||
$this->user = $user;
|
|
||||||
$this->process_command();
|
|
||||||
} else {
|
|
||||||
//basic authentication failed
|
|
||||||
list($proxy, $ip) = common_client_ip();
|
|
||||||
|
|
||||||
common_log(LOG_WARNING, "Failed API auth attempt, nickname = $nickname, proxy = $proxy, ip = $ip.");
|
|
||||||
$this->show_basic_auth_error();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// Caller might give us a username even if not required
|
|
||||||
if (isset($this->auth_user)) {
|
|
||||||
$user = User::staticGet('nickname', $this->auth_user);
|
|
||||||
if ($user) {
|
|
||||||
$this->user = $user;
|
|
||||||
}
|
|
||||||
//Twitter doesn't throw an error if the user isn't found
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->process_command();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function process_command()
|
|
||||||
{
|
|
||||||
$action = "twitapi$this->api_action";
|
|
||||||
$actionfile = INSTALLDIR."/actions/$action.php";
|
|
||||||
|
|
||||||
if (file_exists($actionfile)) {
|
|
||||||
include_once $actionfile;
|
|
||||||
$action_class = ucfirst($action)."Action";
|
|
||||||
$action_obj = new $action_class();
|
|
||||||
|
|
||||||
if (!$action_obj->prepare($this->args)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (method_exists($action_obj, $this->api_method)) {
|
|
||||||
$apidata = array( 'content-type' => $this->content_type,
|
|
||||||
'api_method' => $this->api_method,
|
|
||||||
'api_arg' => $this->api_arg,
|
|
||||||
'user' => $this->user);
|
|
||||||
|
|
||||||
call_user_func(array($action_obj, $this->api_method), $_REQUEST, $apidata);
|
|
||||||
} else {
|
|
||||||
$this->clientError("API method not found!", $code = 404);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$this->clientError("API method not found!", $code = 404);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Whitelist of API methods that don't need authentication
|
|
||||||
function requires_auth()
|
|
||||||
{
|
|
||||||
static $noauth = array( 'statuses/public_timeline',
|
|
||||||
'statuses/show',
|
|
||||||
'users/show',
|
|
||||||
'help/test',
|
|
||||||
'help/downtime_schedule',
|
|
||||||
'statusnet/version',
|
|
||||||
'statusnet/config',
|
|
||||||
'statusnet/wadl',
|
|
||||||
'tags/timeline',
|
|
||||||
'oembed/oembed',
|
|
||||||
'groups/show',
|
|
||||||
'groups/timeline',
|
|
||||||
'groups/list_all',
|
|
||||||
'groups/membership',
|
|
||||||
'groups/is_member',
|
|
||||||
'groups/timeline');
|
|
||||||
|
|
||||||
static $bareauth = array('statuses/user_timeline',
|
|
||||||
'statuses/friends_timeline',
|
|
||||||
'statuses/home_timeline',
|
|
||||||
'statuses/friends',
|
|
||||||
'statuses/replies',
|
|
||||||
'statuses/mentions',
|
|
||||||
'statuses/followers',
|
|
||||||
'favorites/favorites',
|
|
||||||
'friendships/show',
|
|
||||||
'groups/list_groups');
|
|
||||||
|
|
||||||
$fullname = "$this->api_action/$this->api_method";
|
|
||||||
|
|
||||||
// If the site is "private", all API methods except statusnet/config
|
|
||||||
// need authentication
|
|
||||||
|
|
||||||
if (common_config('site', 'private')) {
|
|
||||||
return $fullname != 'statusnet/config' || false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// bareauth: only needs auth if without an argument or query param specifying user
|
|
||||||
|
|
||||||
if (in_array($fullname, $bareauth)) {
|
|
||||||
|
|
||||||
// Special case: friendships/show only needs auth if source_id or
|
|
||||||
// source_screen_name is not specified as a param
|
|
||||||
|
|
||||||
if ($fullname == 'friendships/show') {
|
|
||||||
|
|
||||||
$source_id = $this->arg('source_id');
|
|
||||||
$source_screen_name = $this->arg('source_screen_name');
|
|
||||||
|
|
||||||
if (empty($source_id) && empty($source_screen_name)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if all of these are empty, auth is required
|
|
||||||
|
|
||||||
$id = $this->arg('id');
|
|
||||||
$user_id = $this->arg('user_id');
|
|
||||||
$screen_name = $this->arg('screen_name');
|
|
||||||
|
|
||||||
if (empty($this->api_arg)
|
|
||||||
&& empty($id)
|
|
||||||
&& empty($user_id)
|
|
||||||
&& empty($screen_name)
|
|
||||||
) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (in_array($fullname, $noauth)) {
|
|
||||||
|
|
||||||
// noauth: never needs auth
|
|
||||||
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// everybody else needs auth
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function basic_auth_process_header()
|
|
||||||
{
|
|
||||||
if (isset($_SERVER['AUTHORIZATION']) || isset($_SERVER['HTTP_AUTHORIZATION'])) {
|
|
||||||
$authorization_header = isset($_SERVER['HTTP_AUTHORIZATION'])? $_SERVER['HTTP_AUTHORIZATION'] : $_SERVER['AUTHORIZATION'];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_SERVER['PHP_AUTH_USER'])) {
|
|
||||||
$this->auth_user = $_SERVER['PHP_AUTH_USER'];
|
|
||||||
$this->auth_pw = $_SERVER['PHP_AUTH_PW'];
|
|
||||||
} elseif (isset($authorization_header) && strstr(substr($authorization_header, 0, 5), 'Basic')) {
|
|
||||||
// decode the HTTP_AUTHORIZATION header on php-cgi server self
|
|
||||||
// on fcgid server the header name is AUTHORIZATION
|
|
||||||
|
|
||||||
$auth_hash = base64_decode(substr($authorization_header, 6));
|
|
||||||
list($this->auth_user, $this->auth_pw) = explode(':', $auth_hash);
|
|
||||||
|
|
||||||
// set all to null on a empty basic auth request
|
|
||||||
if ($this->auth_user == "") {
|
|
||||||
$this->auth_user = null;
|
|
||||||
$this->auth_pw = null;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$this->auth_user = null;
|
|
||||||
$this->auth_pw = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function show_basic_auth_error()
|
|
||||||
{
|
|
||||||
header('HTTP/1.1 401 Unauthorized');
|
|
||||||
$msg = 'Could not authenticate you.';
|
|
||||||
|
|
||||||
if ($this->content_type == 'xml') {
|
|
||||||
header('Content-Type: application/xml; charset=utf-8');
|
|
||||||
$this->startXML();
|
|
||||||
$this->elementStart('hash');
|
|
||||||
$this->element('error', null, $msg);
|
|
||||||
$this->element('request', null, $_SERVER['REQUEST_URI']);
|
|
||||||
$this->elementEnd('hash');
|
|
||||||
$this->endXML();
|
|
||||||
} else if ($this->content_type == 'json') {
|
|
||||||
header('Content-Type: application/json; charset=utf-8');
|
|
||||||
$error_array = array('error' => $msg, 'request' => $_SERVER['REQUEST_URI']);
|
|
||||||
print(json_encode($error_array));
|
|
||||||
} else {
|
|
||||||
header('Content-type: text/plain');
|
|
||||||
print "$msg\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function isReadOnly($args)
|
|
||||||
{
|
|
||||||
$apiaction = $args['apiaction'];
|
|
||||||
$method = $args['method'];
|
|
||||||
|
|
||||||
list($cmdtext, $fmt) = explode('.', $method);
|
|
||||||
|
|
||||||
static $write_methods = array(
|
|
||||||
'account' => array('update_location', 'update_delivery_device', 'end_session'),
|
|
||||||
'blocks' => array('create', 'destroy'),
|
|
||||||
'direct_messages' => array('create', 'destroy'),
|
|
||||||
'favorites' => array('create', 'destroy'),
|
|
||||||
'friendships' => array('create', 'destroy'),
|
|
||||||
'help' => array(),
|
|
||||||
'notifications' => array('follow', 'leave'),
|
|
||||||
'statuses' => array('update', 'destroy'),
|
|
||||||
'users' => array()
|
|
||||||
);
|
|
||||||
|
|
||||||
if (array_key_exists($apiaction, $write_methods)) {
|
|
||||||
if (!in_array($cmdtext, $write_methods[$apiaction])) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
112
actions/apiaccountratelimitstatus.php
Normal file
112
actions/apiaccountratelimitstatus.php
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Dummy action that emulates Twitter's rate limit status API resource
|
||||||
|
*
|
||||||
|
* 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 Evan Prodromou <evan@status.net>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @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';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We don't have a rate limit, but some clients check this method.
|
||||||
|
* It always returns the same thing: 150 hits left.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @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 ApiAccountRateLimitStatusAction extends ApiBareAuthAction
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Return some Twitter-ish data about API limits
|
||||||
|
*
|
||||||
|
* @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!'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$reset = new DateTime();
|
||||||
|
$reset->modify('+1 hour');
|
||||||
|
|
||||||
|
$this->initDocument($this->format);
|
||||||
|
|
||||||
|
if ($this->format == 'xml') {
|
||||||
|
$this->elementStart('hash');
|
||||||
|
$this->element('remaining-hits', array('type' => 'integer'), 150);
|
||||||
|
$this->element('hourly-limit', array('type' => 'integer'), 150);
|
||||||
|
$this->element(
|
||||||
|
'reset-time', array('type' => 'datetime'),
|
||||||
|
common_date_iso8601($reset->format('r'))
|
||||||
|
);
|
||||||
|
$this->element(
|
||||||
|
'reset_time_in_seconds',
|
||||||
|
array('type' => 'integer'),
|
||||||
|
strtotime('+1 hour')
|
||||||
|
);
|
||||||
|
$this->elementEnd('hash');
|
||||||
|
} elseif ($this->format == 'json') {
|
||||||
|
$out = array(
|
||||||
|
'reset_time_in_seconds' => strtotime('+1 hour'),
|
||||||
|
'remaining_hits' => 150,
|
||||||
|
'hourly_limit' => 150,
|
||||||
|
'reset_time' => common_date_rfc2822(
|
||||||
|
$reset->format('r')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
print json_encode($out);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->endDocument($this->format);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
85
actions/apiaccountverifycredentials.php
Normal file
85
actions/apiaccountverifycredentials.php
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Test if supplied user credentials are valid.
|
||||||
|
*
|
||||||
|
* 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 Evan Prodromou <evan@status.net>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @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';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check a user's credentials. Returns an HTTP 200 OK response code and a
|
||||||
|
* representation of the requesting user if authentication was successful;
|
||||||
|
* returns a 401 status code and an error message if not.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @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 ApiAccountVerifyCredentialsAction extends ApiAuthAction
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Check whether the credentials are valid and output the result
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
switch ($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
case 'json':
|
||||||
|
$args['id'] = $this->auth_user->id;
|
||||||
|
$action_obj = new ApiUserShowAction();
|
||||||
|
if ($action_obj->prepare($args)) {
|
||||||
|
$action_obj->handle($args);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
header('Content-Type: text/html; charset=utf-8');
|
||||||
|
print 'Authorized';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
114
actions/apiblockcreate.php
Normal file
114
actions/apiblockcreate.php
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Block a user via 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 Evan Prodromou <evan@status.net>
|
||||||
|
* @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';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Blocks the user specified in the ID parameter as the authenticating user.
|
||||||
|
* Destroys a friendship to the blocked user if it exists. Returns the
|
||||||
|
* blocked user in the requested format when successful.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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 ApiBlockCreateAction extends ApiAuthAction
|
||||||
|
{
|
||||||
|
var $other = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->auth_user;
|
||||||
|
$this->other = $this->getTargetUser($this->arg('id'));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Save the new message
|
||||||
|
*
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->user) || empty($this->other)) {
|
||||||
|
$this->clientError(_('No such user!'), 404, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->user->hasBlocked($this->other)
|
||||||
|
|| $this->user->block($this->other)
|
||||||
|
) {
|
||||||
|
$this->initDocument($this->format);
|
||||||
|
$this->showProfile($this->other, $this->format);
|
||||||
|
$this->endDocument($this->format);
|
||||||
|
} else {
|
||||||
|
$this->serverError(_('Block user failed.'), 500, $this->format);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
113
actions/apiblockdestroy.php
Normal file
113
actions/apiblockdestroy.php
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Un-block a user via 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 Evan Prodromou <evan@status.net>
|
||||||
|
* @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';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Un-blocks the user specified in the ID parameter for the authenticating user.
|
||||||
|
* Returns the un-blocked user in the requested format when successful.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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 ApiBlockDestroyAction extends ApiAuthAction
|
||||||
|
{
|
||||||
|
var $other = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->auth_user;
|
||||||
|
$this->other = $this->getTargetUser($this->arg('id'));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Save the new message
|
||||||
|
*
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->user) || empty($this->other)) {
|
||||||
|
$this->clientError(_('No such user!'), 404, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->user->hasBlocked($this->other)
|
||||||
|
|| $this->user->unblock($this->other)
|
||||||
|
) {
|
||||||
|
$this->initDocument($this->format);
|
||||||
|
$this->showProfile($this->other, $this->format);
|
||||||
|
$this->endDocument($this->format);
|
||||||
|
} else {
|
||||||
|
$this->serverError(_('Unblock user failed.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
375
actions/apidirectmessage.php
Normal file
375
actions/apidirectmessage.php
Normal file
@ -0,0 +1,375 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Show a the direct messages from or to a user
|
||||||
|
*
|
||||||
|
* 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 Adrian Lang <mail@adrianlang.de>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @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';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show a list of direct messages from or to the authenticating user
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Adrian Lang <mail@adrianlang.de>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @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 ApiDirectMessageAction extends ApiAuthAction
|
||||||
|
{
|
||||||
|
var $messages = null;
|
||||||
|
var $title = null;
|
||||||
|
var $subtitle = null;
|
||||||
|
var $link = null;
|
||||||
|
var $selfuri_base = null;
|
||||||
|
var $id = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->auth_user;
|
||||||
|
|
||||||
|
if (empty($this->user)) {
|
||||||
|
$this->clientError(_('No such user!'), 404, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$server = common_root_url();
|
||||||
|
$taguribase = common_config('integration', 'taguri');
|
||||||
|
|
||||||
|
if ($this->arg('sent')) {
|
||||||
|
|
||||||
|
// Action was called by /api/direct_messages/sent.format
|
||||||
|
|
||||||
|
$this->title = sprintf(
|
||||||
|
_("Direct messages from %s"),
|
||||||
|
$this->user->nickname
|
||||||
|
);
|
||||||
|
$this->subtitle = sprintf(
|
||||||
|
_("All the direct messages sent from %s"),
|
||||||
|
$this->user->nickname
|
||||||
|
);
|
||||||
|
$this->link = $server . $this->user->nickname . '/outbox';
|
||||||
|
$this->selfuri_base = common_root_url() . 'api/direct_messages/sent';
|
||||||
|
$this->id = "tag:$taguribase:SentDirectMessages:" . $this->user->id;
|
||||||
|
} else {
|
||||||
|
$this->title = sprintf(
|
||||||
|
_("Direct messages to %s"),
|
||||||
|
$this->user->nickname
|
||||||
|
);
|
||||||
|
$this->subtitle = sprintf(
|
||||||
|
_("All the direct messages sent to %s"),
|
||||||
|
$this->user->nickname
|
||||||
|
);
|
||||||
|
$this->link = $server . $this->user->nickname . '/inbox';
|
||||||
|
$this->selfuri_base = common_root_url() . 'api/direct_messages';
|
||||||
|
$this->id = "tag:$taguribase:DirectMessages:" . $this->user->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->messages = $this->getMessages();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Show the messages
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
$this->showMessages();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the messages
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function showMessages()
|
||||||
|
{
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showXmlDirectMessages();
|
||||||
|
break;
|
||||||
|
case 'rss':
|
||||||
|
$this->showRssDirectMessages();
|
||||||
|
break;
|
||||||
|
case 'atom':
|
||||||
|
$this->showAtomDirectMessages();
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showJsonDirectMessages();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(_('API method not found!'), $code = 404);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get notices
|
||||||
|
*
|
||||||
|
* @return array notices
|
||||||
|
*/
|
||||||
|
|
||||||
|
function getMessages()
|
||||||
|
{
|
||||||
|
$message = new Message();
|
||||||
|
|
||||||
|
if ($this->arg('sent')) {
|
||||||
|
$message->from_profile = $this->user->id;
|
||||||
|
} else {
|
||||||
|
$message->to_profile = $this->user->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($this->max_id)) {
|
||||||
|
$message->whereAdd('id <= ' . $this->max_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($this->since_id)) {
|
||||||
|
$message->whereAdd('id > ' . $this->since_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($since)) {
|
||||||
|
$d = date('Y-m-d H:i:s', $this->since);
|
||||||
|
$message->whereAdd("created > '$d'");
|
||||||
|
}
|
||||||
|
|
||||||
|
$message->orderBy('created DESC, id DESC');
|
||||||
|
$message->limit((($this->page - 1) * $this->count), $this->count);
|
||||||
|
$message->find();
|
||||||
|
|
||||||
|
$messages = array();
|
||||||
|
|
||||||
|
while ($message->fetch()) {
|
||||||
|
$messages[] = clone($message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $messages;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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->messages)) {
|
||||||
|
return strtotime($this->messages[0]->created);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a list of direct messages as Twitter-style XML array
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function showXmlDirectMessages()
|
||||||
|
{
|
||||||
|
$this->initDocument('xml');
|
||||||
|
$this->elementStart('direct-messages', array('type' => 'array'));
|
||||||
|
|
||||||
|
foreach ($this->messages as $m) {
|
||||||
|
$dm_array = $this->directMessageArray($m);
|
||||||
|
$this->showXmlDirectMessage($dm_array);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->elementEnd('direct-messages');
|
||||||
|
$this->endDocument('xml');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a list of direct messages as a JSON encoded array
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function showJsonDirectMessages()
|
||||||
|
{
|
||||||
|
$this->initDocument('json');
|
||||||
|
|
||||||
|
$dmsgs = array();
|
||||||
|
|
||||||
|
foreach ($this->messages as $m) {
|
||||||
|
$dm_array = $this->directMessageArray($m);
|
||||||
|
array_push($dmsgs, $dm_array);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->showJsonObjects($dmsgs);
|
||||||
|
$this->endDocument('json');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a list of direct messages as RSS items
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function showRssDirectMessages()
|
||||||
|
{
|
||||||
|
$this->initDocument('rss');
|
||||||
|
|
||||||
|
$this->element('title', null, $this->title);
|
||||||
|
|
||||||
|
$this->element('link', null, $this->link);
|
||||||
|
$this->element('description', null, $this->subtitle);
|
||||||
|
$this->element('language', null, 'en-us');
|
||||||
|
|
||||||
|
$this->element(
|
||||||
|
'atom:link',
|
||||||
|
array(
|
||||||
|
'type' => 'application/rss+xml',
|
||||||
|
'href' => $this->selfuri_base . '.rss',
|
||||||
|
'rel' => self
|
||||||
|
),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
$this->element('ttl', null, '40');
|
||||||
|
|
||||||
|
foreach ($this->messages as $m) {
|
||||||
|
$entry = $this->rssDirectMessageArray($m);
|
||||||
|
$this->showTwitterRssItem($entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->endTwitterRss();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a list of direct messages as Atom entries
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function showAtomDirectMessages()
|
||||||
|
{
|
||||||
|
$this->initDocument('atom');
|
||||||
|
|
||||||
|
$this->element('title', null, $this->title);
|
||||||
|
$this->element('id', null, $this->id);
|
||||||
|
|
||||||
|
$selfuri = common_root_url() . 'api/direct_messages.atom';
|
||||||
|
|
||||||
|
$this->element(
|
||||||
|
'link', array(
|
||||||
|
'href' => $this->link,
|
||||||
|
'rel' => 'alternate',
|
||||||
|
'type' => 'text/html'),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
$this->element(
|
||||||
|
'link', array(
|
||||||
|
'href' => $this->selfuri_base . '.atom', 'rel' => 'self',
|
||||||
|
'type' => 'application/atom+xml'),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
$this->element('updated', null, common_date_iso8601('now'));
|
||||||
|
$this->element('subtitle', null, $this->subtitle);
|
||||||
|
|
||||||
|
foreach ($this->messages as $m) {
|
||||||
|
$entry = $this->rssDirectMessageArray($m);
|
||||||
|
$this->showTwitterAtomEntry($entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->endDocument('atom');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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->messages)) {
|
||||||
|
|
||||||
|
$last = count($this->messages) - 1;
|
||||||
|
|
||||||
|
return '"' . implode(
|
||||||
|
':',
|
||||||
|
array($this->arg('action'),
|
||||||
|
common_language(),
|
||||||
|
strtotime($this->messages[0]->created),
|
||||||
|
strtotime($this->messages[$last]->created)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
. '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
188
actions/apidirectmessagenew.php
Normal file
188
actions/apidirectmessagenew.php
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Send a direct message via 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 Adrian Lang <mail@adrianlang.de>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @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';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new direct message from the authenticating user to
|
||||||
|
* the user specified by id.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Adrian Lang <mail@adrianlang.de>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @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 ApiDirectMessageNewAction extends ApiAuthAction
|
||||||
|
{
|
||||||
|
var $source = null;
|
||||||
|
var $other = null;
|
||||||
|
var $content = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->auth_user;
|
||||||
|
|
||||||
|
if (empty($this->user)) {
|
||||||
|
$this->clientError(_('No such user!'), 404, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->source = $this->trimmed('source'); // Not supported by Twitter.
|
||||||
|
|
||||||
|
$reserved_sources = array('web', 'omb', 'mail', 'xmpp', 'api');
|
||||||
|
if (empty($thtis->source) || in_array($this->source, $reserved_sources)) {
|
||||||
|
$source = 'api';
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->content = $this->trimmed('text');
|
||||||
|
|
||||||
|
$this->user = $this->auth_user;
|
||||||
|
|
||||||
|
$user_param = $this->trimmed('user');
|
||||||
|
$user_id = $this->arg('user_id');
|
||||||
|
$screen_name = $this->trimmed('screen_name');
|
||||||
|
|
||||||
|
if (isset($user_param) || isset($user_id) || isset($screen_name)) {
|
||||||
|
$this->other = $this->getTargetUser($user_param);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Save the new message
|
||||||
|
*
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->content)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('No message text!'),
|
||||||
|
406,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$content_shortened = common_shorten_links($this->content);
|
||||||
|
if (Message::contentTooLong($content_shortened)) {
|
||||||
|
$this->clientError(
|
||||||
|
sprintf(
|
||||||
|
_('That\'s too long. Max message size is %d chars.'),
|
||||||
|
Message::maxContent()
|
||||||
|
),
|
||||||
|
406,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->other)) {
|
||||||
|
$this->clientError(_('Recipient user not found.'), 403, $this->format);
|
||||||
|
return;
|
||||||
|
} else if (!$this->user->mutuallySubscribed($this->other)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('Can\'t send direct messages to users who aren\'t your friend.'),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
} else if ($this->user->id == $this->other->id) {
|
||||||
|
|
||||||
|
// Note: sending msgs to yourself is allowed by Twitter
|
||||||
|
|
||||||
|
$errmsg = 'Don\'t send a message to yourself; ' .
|
||||||
|
'just say it to yourself quietly instead.'
|
||||||
|
|
||||||
|
$this->clientError(_($errmsg), 403, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$message = Message::saveNew(
|
||||||
|
$this->user->id,
|
||||||
|
$this->other->id,
|
||||||
|
html_entity_decode($this->content, ENT_NOQUOTES, 'UTF-8'),
|
||||||
|
$this->source
|
||||||
|
);
|
||||||
|
|
||||||
|
if (is_string($message)) {
|
||||||
|
$this->serverError($message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mail_notify_message($message, $this->user, $this->other);
|
||||||
|
|
||||||
|
if ($this->format == 'xml') {
|
||||||
|
$this->showSingleXmlDirectMessage($message);
|
||||||
|
} elseif ($this->format == 'json') {
|
||||||
|
$this->showSingleJsondirectMessage($message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
168
actions/apifavoritecreate.php
Normal file
168
actions/apifavoritecreate.php
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Add a notice to a user's list of favorite notices via 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 Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Favorites the status specified in the ID parameter as the authenticating user.
|
||||||
|
* Returns the favorite status when successful.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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 ApiFavoriteCreateAction extends ApiAuthAction
|
||||||
|
{
|
||||||
|
var $notice = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->auth_user;
|
||||||
|
$this->notice = Notice::staticGet($this->arg('id'));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Check the format and show the user info
|
||||||
|
*
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_array($this->format, array('xml', 'json'))) {
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found!'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->notice)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('No status found with that ID.'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: Twitter lets you fave things repeatedly via API.
|
||||||
|
|
||||||
|
if ($this->user->hasFave($this->notice)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('This status is already a favorite!'),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$fave = Fave::addNew($this->user, $this->notice);
|
||||||
|
|
||||||
|
if (empty($fave)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('Could not create favorite.')
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->notify($fave, $this->notice, $this->user);
|
||||||
|
$this->user->blowFavesCache();
|
||||||
|
|
||||||
|
if ($this->format == 'xml') {
|
||||||
|
$this->showSingleXmlStatus($this->notice);
|
||||||
|
} elseif ($this->format == 'json') {
|
||||||
|
$this->show_single_json_status($this->notice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify the author of the favorite that the user likes their notice
|
||||||
|
*
|
||||||
|
* @param Favorite $fave the favorite in question
|
||||||
|
* @param Notice $notice the notice that's been faved
|
||||||
|
* @param User $user the user doing the favoriting
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function notify($fave, $notice, $user)
|
||||||
|
{
|
||||||
|
$other = User::staticGet('id', $notice->profile_id);
|
||||||
|
if ($other && $other->id != $user->id) {
|
||||||
|
if ($other->email && $other->emailnotifyfav) {
|
||||||
|
mail_notify_fave($other, $user, $notice);
|
||||||
|
}
|
||||||
|
// XXX: notify by IM
|
||||||
|
// XXX: notify by SMS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
150
actions/apifavoritedestroy.php
Normal file
150
actions/apifavoritedestroy.php
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Remote a notice from a user's list of favorite notices via 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 Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Un-favorites the status specified in the ID parameter as the authenticating user.
|
||||||
|
* Returns the un-favorited status in the requested format when successful.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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 ApiFavoriteDestroyAction extends ApiAuthAction
|
||||||
|
{
|
||||||
|
|
||||||
|
var $notice = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->auth_user;
|
||||||
|
$this->notice = Notice::staticGet($this->arg('id'));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Check the format and show the user info
|
||||||
|
*
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_array($this->format, array('xml', 'json'))) {
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found!'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->notice)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('No status found with that ID.'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$fave = new Fave();
|
||||||
|
$fave->user_id = $this->user->id;
|
||||||
|
$fave->notice_id = $this->notice->id;
|
||||||
|
|
||||||
|
if (!$fave->find(true)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('That status is not a favorite!'),
|
||||||
|
403,
|
||||||
|
$this->favorite
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $fave->delete();
|
||||||
|
|
||||||
|
if (!$result) {
|
||||||
|
common_log_db_error($fave, 'DELETE', __FILE__);
|
||||||
|
$this->clientError(
|
||||||
|
_('Could not delete favorite.'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->user->blowFavesCache();
|
||||||
|
|
||||||
|
if ($this->format == 'xml') {
|
||||||
|
$this->showSingleXmlStatus($this->notice);
|
||||||
|
} elseif ($this->format == 'json') {
|
||||||
|
$this->show_single_json_status($this->notice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
137
actions/apifriendshipscreate.php
Normal file
137
actions/apifriendshipscreate.php
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Subscribe to a user via 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 Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows the authenticating users to follow (subscribe) the user specified in
|
||||||
|
* the ID parameter. Returns the befriended user in the requested format when
|
||||||
|
* successful. Returns a string describing the failure condition when unsuccessful.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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 ApiFriendshipsCreateAction extends ApiAuthAction
|
||||||
|
{
|
||||||
|
var $other = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->auth_user;
|
||||||
|
$this->other = $this->getTargetUser($id);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Check the format and show the user info
|
||||||
|
*
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_array($this->format, array('xml', 'json'))) {
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found!'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->other)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('Could not follow user: User not found.'),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->user->isSubscribed($this->other)) {
|
||||||
|
$errmsg = sprintf(
|
||||||
|
_('Could not follow user: %s is already on your list.'),
|
||||||
|
$this->other->nickname
|
||||||
|
);
|
||||||
|
$this->clientError($errmsg, 403, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = subs_subscribe_to($this->user, $this->other);
|
||||||
|
|
||||||
|
if (is_string($result)) {
|
||||||
|
$this->clientError($result, 403, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->initDocument($this->format);
|
||||||
|
$this->showProfile($this->other, $this->format);
|
||||||
|
$this->endDocument($this->format);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
139
actions/apifriendshipsdestroy.php
Normal file
139
actions/apifriendshipsdestroy.php
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Unsubscribe to a user via 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 Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows the authenticating users to unfollow (unsubscribe) the user specified in
|
||||||
|
* the ID parameter. Returns the unfollowed user in the requested format when
|
||||||
|
* successful. Returns a string describing the failure condition when unsuccessful.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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 ApiFriendshipsDestroyAction extends ApiAuthAction
|
||||||
|
{
|
||||||
|
var $other = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->auth_user;
|
||||||
|
$this->other = $this->getTargetUser($id);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Check the format and show the user info
|
||||||
|
*
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_array($this->format, array('xml', 'json'))) {
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found!'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->other)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('Could not unfollow user: User not found.'),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't allow unsubscribing from yourself!
|
||||||
|
|
||||||
|
if ($this->user->id == $this->other->id) {
|
||||||
|
$this->clientError(
|
||||||
|
_("You cannot unfollow yourself!"),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = subs_unsubscribe_user($this->user, $this->other->nickname);
|
||||||
|
|
||||||
|
if (is_string($result)) {
|
||||||
|
$this->clientError($result, 403, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->initDocument($this->format);
|
||||||
|
$this->showProfile($this->other, $this->format);
|
||||||
|
$this->endDocument($this->format);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
128
actions/apifriendshipsexists.php
Normal file
128
actions/apifriendshipsexists.php
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Show whether there is a friendship between two users
|
||||||
|
*
|
||||||
|
* 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 Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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/api.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for the existence of friendship between two users. Will return true if
|
||||||
|
* user_a follows user_b, otherwise will return false.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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 ApiFriendshipsExistsAction extends ApiAction
|
||||||
|
{
|
||||||
|
var $user_a = null;
|
||||||
|
var $user_b = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$user_a_id = $this->trimmed('user_a');
|
||||||
|
$user_b_id = $this->trimmed('user_b');
|
||||||
|
|
||||||
|
common_debug("user_a = " . $user_a_id);
|
||||||
|
common_debug("user_b = " . $user_b_id);
|
||||||
|
|
||||||
|
|
||||||
|
$this->user_a = $this->getTargetUser($user_a_id);
|
||||||
|
|
||||||
|
if (empty($this->user_a)) {
|
||||||
|
common_debug('gargargra');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->user_b = $this->getTargetUser($user_b_id);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Check the format and show the user info
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
if (empty($this->user_a) || empty($this->user_b)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('Two user ids or screen_names must be supplied.'),
|
||||||
|
400,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $this->user_a->isSubscribed($this->user_b);
|
||||||
|
|
||||||
|
switch ($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->initDocument('xml');
|
||||||
|
$this->element('friends', null, $result);
|
||||||
|
$this->endDocument('xml');
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->initDocument('json');
|
||||||
|
print json_encode($result);
|
||||||
|
$this->endDocument('json');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
168
actions/apifriendshipsshow.php
Normal file
168
actions/apifriendshipsshow.php
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Show information about the relationship between two users
|
||||||
|
*
|
||||||
|
* 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 Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Outputs detailed information about the relationship between two users
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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 ApiFriendshipsShowAction extends ApiBareAuthAction
|
||||||
|
{
|
||||||
|
var $source = null;
|
||||||
|
var $target = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$source_id = (int)$this->trimmed('source_id');
|
||||||
|
$source_screen_name = $this->trimmed('source_screen_name');
|
||||||
|
$target_id = (int)$this->trimmed('target_id');
|
||||||
|
$target_screen_name = $this->trimmed('target_screen_name');
|
||||||
|
|
||||||
|
if (!empty($source_id)) {
|
||||||
|
$this->source = User::staticGet($source_id);
|
||||||
|
} elseif (!empty($source_screen_name)) {
|
||||||
|
$this->source = User::staticGet('nickname', $source_screen_name);
|
||||||
|
} else {
|
||||||
|
$this->source = $this->auth_user;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($target_id)) {
|
||||||
|
$this->target = User::staticGet($target_id);
|
||||||
|
} elseif (!empty($target_screen_name)) {
|
||||||
|
$this->target = User::staticGet('nickname', $target_screen_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines whether this API resource requires auth. Overloaded to look
|
||||||
|
* return true in case source_id and source_screen_name are both empty
|
||||||
|
*
|
||||||
|
* @return boolean true or false
|
||||||
|
*/
|
||||||
|
|
||||||
|
function requiresAuth()
|
||||||
|
{
|
||||||
|
if (common_config('site', 'private')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$source_id = $this->trimmed('source_id');
|
||||||
|
$source_screen_name = $this->trimmed('source_screen_name');
|
||||||
|
|
||||||
|
if (empty($source_id) && empty($source_screen_name)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Check the format and show the user info
|
||||||
|
*
|
||||||
|
* @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!'), 404);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->source)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('Could not determine source user.'),
|
||||||
|
404
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->target)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('Could not find target user.'),
|
||||||
|
404
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $this->twitterRelationshipArray($this->source, $this->target);
|
||||||
|
|
||||||
|
switch ($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->initDocument('xml');
|
||||||
|
$this->showTwitterXmlRelationship($result[relationship]);
|
||||||
|
$this->endDocument('xml');
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->initDocument('json');
|
||||||
|
print json_encode($result);
|
||||||
|
$this->endDocument('json');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
381
actions/apigroupcreate.php
Normal file
381
actions/apigroupcreate.php
Normal file
@ -0,0 +1,381 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Create a group via 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 Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @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';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make a new group. Sets the authenticated user as the administrator of the group.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @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 ApiGroupCreateAction extends ApiAuthAction
|
||||||
|
{
|
||||||
|
var $group = null;
|
||||||
|
var $nickname = null;
|
||||||
|
var $fullname = null;
|
||||||
|
var $homepage = null;
|
||||||
|
var $description = null;
|
||||||
|
var $location = null;
|
||||||
|
var $aliasstring = null;
|
||||||
|
var $aliases = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->auth_user;
|
||||||
|
|
||||||
|
$this->nickname = $this->arg('nickname');
|
||||||
|
$this->fullname = $this->arg('full_name');
|
||||||
|
$this->homepage = $this->arg('homepage');
|
||||||
|
$this->description = $this->arg('description');
|
||||||
|
$this->location = $this->arg('location');
|
||||||
|
$this->aliasstring = $this->arg('aliases');
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Save the new group
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
if (!common_config('inboxes', 'enabled')) {
|
||||||
|
$this->serverError(
|
||||||
|
_('Inboxes must be enabled for groups to work'),
|
||||||
|
400,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||||
|
$this->clientError(
|
||||||
|
_('This method requires a POST.'),
|
||||||
|
400,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->user)) {
|
||||||
|
$this->clientError(_('No such user!'), 404, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->validateParams() == false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$group = new User_group();
|
||||||
|
|
||||||
|
$group->query('BEGIN');
|
||||||
|
|
||||||
|
$group->nickname = $this->nickname;
|
||||||
|
$group->fullname = $this->fullname;
|
||||||
|
$group->homepage = $this->homepage;
|
||||||
|
$group->description = $this->description;
|
||||||
|
$group->location = $this->location;
|
||||||
|
$group->created = common_sql_now();
|
||||||
|
|
||||||
|
$result = $group->insert();
|
||||||
|
|
||||||
|
if (!$result) {
|
||||||
|
common_log_db_error($group, 'INSERT', __FILE__);
|
||||||
|
$this->serverError(
|
||||||
|
_('Could not create group.'),
|
||||||
|
500,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $group->setAliases($this->aliases);
|
||||||
|
|
||||||
|
if (!$result) {
|
||||||
|
$this->serverError(
|
||||||
|
_('Could not create aliases.'),
|
||||||
|
500,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$member = new Group_member();
|
||||||
|
|
||||||
|
$member->group_id = $group->id;
|
||||||
|
$member->profile_id = $this->user->id;
|
||||||
|
$member->is_admin = 1;
|
||||||
|
$member->created = $group->created;
|
||||||
|
|
||||||
|
$result = $member->insert();
|
||||||
|
|
||||||
|
if (!$result) {
|
||||||
|
common_log_db_error($member, 'INSERT', __FILE__);
|
||||||
|
$this->serverError(
|
||||||
|
_('Could not set group membership.'),
|
||||||
|
500,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$group->query('COMMIT');
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showSingleXmlGroup($group);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showSingleJsonGroup($group);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found!'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate params for the new group
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function validateParams()
|
||||||
|
{
|
||||||
|
$valid = Validate::string(
|
||||||
|
$this->nickname, array(
|
||||||
|
'min_length' => 1,
|
||||||
|
'max_length' => 64,
|
||||||
|
'format' => NICKNAME_FMT
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!$valid) {
|
||||||
|
$this->clientError(
|
||||||
|
_(
|
||||||
|
'Nickname must have only lowercase letters ' .
|
||||||
|
'and numbers and no spaces.'
|
||||||
|
),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
} elseif ($this->groupNicknameExists($this->nickname)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('Nickname already in use. Try another one.'),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
} else if (!User_group::allowedNickname($this->nickname)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('Not a valid nickname.'),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
|
||||||
|
} elseif (
|
||||||
|
!is_null($this->homepage)
|
||||||
|
&& strlen($this->homepage) > 0
|
||||||
|
&& !Validate::uri(
|
||||||
|
$this->homepage, array(
|
||||||
|
'allowed_schemes' =>
|
||||||
|
array('http', 'https')
|
||||||
|
)
|
||||||
|
)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('Homepage is not a valid URL.'),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
} elseif (
|
||||||
|
!is_null($this->fullname)
|
||||||
|
&& mb_strlen($this->fullname) > 255) {
|
||||||
|
$this->clientError(
|
||||||
|
_('Full name is too long (max 255 chars).'),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
} elseif (User_group::descriptionTooLong($this->description)) {
|
||||||
|
$this->clientError(
|
||||||
|
sprintf(
|
||||||
|
_('Description is too long (max %d chars).'),
|
||||||
|
User_group::maxDescription()
|
||||||
|
),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
} elseif (
|
||||||
|
!is_null($this->location)
|
||||||
|
&& mb_strlen($this->location) > 255) {
|
||||||
|
$this->clientError(
|
||||||
|
_('Location is too long (max 255 chars).'),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($this->aliasstring)) {
|
||||||
|
$this->aliases = array_map(
|
||||||
|
'common_canonical_nickname',
|
||||||
|
array_unique(preg_split('/[\s,]+/', $this->aliasstring))
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$this->aliases = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($this->aliases) > common_config('group', 'maxaliases')) {
|
||||||
|
$this->clientError(
|
||||||
|
sprintf(
|
||||||
|
_('Too many aliases! Maximum %d.'),
|
||||||
|
common_config('group', 'maxaliases')
|
||||||
|
),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->aliases as $alias) {
|
||||||
|
|
||||||
|
$valid = Validate::string(
|
||||||
|
$alias, array(
|
||||||
|
'min_length' => 1,
|
||||||
|
'max_length' => 64,
|
||||||
|
'format' => NICKNAME_FMT
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!$valid) {
|
||||||
|
$this->clientError(
|
||||||
|
sprintf(_('Invalid alias: "%s"'), $alias),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ($this->groupNicknameExists($alias)) {
|
||||||
|
$this->clientError(
|
||||||
|
sprintf(
|
||||||
|
_('Alias "%s" already in use. Try another one.'),
|
||||||
|
$alias
|
||||||
|
),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX assumes alphanum nicknames
|
||||||
|
|
||||||
|
if (strcmp($alias, $this->nickname) == 0) {
|
||||||
|
$this->clientError(
|
||||||
|
_('Alias can\'t be the same as nickname.'),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evarything looks OK
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check to see whether a nickname is already in use by a group
|
||||||
|
*
|
||||||
|
* @param String $nickname The nickname in question
|
||||||
|
*
|
||||||
|
* @return boolean true or false
|
||||||
|
*/
|
||||||
|
|
||||||
|
function groupNicknameExists($nickname)
|
||||||
|
{
|
||||||
|
$group = User_group::staticGet('nickname', $nickname);
|
||||||
|
|
||||||
|
if (!empty($group)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$alias = Group_alias::staticGet('alias', $nickname);
|
||||||
|
|
||||||
|
if (!empty($alias)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
122
actions/apigroupismember.php
Normal file
122
actions/apigroupismember.php
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Check to see whether a user a member of a group
|
||||||
|
*
|
||||||
|
* 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 Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @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 whether a user is a member of a specified group.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @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 ApiGroupIsMemberAction extends ApiBareAuthAction
|
||||||
|
{
|
||||||
|
var $group = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->getTargetUser(null);
|
||||||
|
$this->group = $this->getTargetGroup(null);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Save the new message
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
if (empty($this->user)) {
|
||||||
|
$this->clientError(_('No such user!'), 404, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->group)) {
|
||||||
|
$this->clientError('Group not found!', 404, $this->format);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$is_member = $this->user->isMember($this->group);
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->initDocument('xml');
|
||||||
|
$this->element('is_member', null, $is_member);
|
||||||
|
$this->endDocument('xml');
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->initDocument('json');
|
||||||
|
$this->showJsonObjects(array('is_member' => $is_member));
|
||||||
|
$this->endDocument('json');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found!'),
|
||||||
|
400,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
163
actions/apigroupjoin.php
Normal file
163
actions/apigroupjoin.php
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Join a group via 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 Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @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';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Joins the authenticated user to the group speicified by ID
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @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 ApiGroupJoinAction extends ApiAuthAction
|
||||||
|
{
|
||||||
|
var $group = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->auth_user;
|
||||||
|
$this->group = $this->getTargetGroup($this->arg('id'));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Save the new message
|
||||||
|
*
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->user)) {
|
||||||
|
$this->clientError(_('No such user!'), 404, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->group)) {
|
||||||
|
$this->clientError('Group not found!', 404, $this->format);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->user->isMember($this->group)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('You are already a member of that group.'),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Group_block::isBlocked($this->group, $this->user->getProfile())) {
|
||||||
|
$this->clientError(
|
||||||
|
_('You have been blocked from that group by the admin.'),
|
||||||
|
403,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$member = new Group_member();
|
||||||
|
|
||||||
|
$member->group_id = $this->group->id;
|
||||||
|
$member->profile_id = $this->user->id;
|
||||||
|
$member->created = common_sql_now();
|
||||||
|
|
||||||
|
$result = $member->insert();
|
||||||
|
|
||||||
|
if (!$result) {
|
||||||
|
common_log_db_error($member, 'INSERT', __FILE__);
|
||||||
|
$this->serverError(
|
||||||
|
sprintf(
|
||||||
|
_('Could not join user %s to group %s.'),
|
||||||
|
$this->user->nickname,
|
||||||
|
$this->group->nickname
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->show_single_xml_group($this->group);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showSingleJsonGroup($this->group);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found!'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
149
actions/apigroupleave.php
Normal file
149
actions/apigroupleave.php
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Leave a group via 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 Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @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';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the authenticated user from the group specified by ID
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @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 ApiGroupLeaveAction extends ApiAuthAction
|
||||||
|
{
|
||||||
|
var $group = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->auth_user;
|
||||||
|
$this->group = $this->getTargetGroup($this->arg('id'));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Save the new message
|
||||||
|
*
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->user)) {
|
||||||
|
$this->clientError(_('No such user!'), 404, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->group)) {
|
||||||
|
$this->clientError('Group not found!', 404, $this->format);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$member = new Group_member();
|
||||||
|
|
||||||
|
$member->group_id = $this->group->id;
|
||||||
|
$member->profile_id = $this->auth->id;
|
||||||
|
|
||||||
|
if (!$member->find(true)) {
|
||||||
|
$this->serverError(_('You are not a member of this group.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $member->delete();
|
||||||
|
|
||||||
|
if (!$result) {
|
||||||
|
common_log_db_error($member, 'INSERT', __FILE__);
|
||||||
|
$this->serverError(
|
||||||
|
sprintf(
|
||||||
|
_('Could not remove user %s to group %s.'),
|
||||||
|
$this->user->nickname,
|
||||||
|
$this->$group->nickname
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->show_single_xml_group($this->group);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showSingleJsonGroup($this->group);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found!'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
223
actions/apigrouplist.php
Normal file
223
actions/apigrouplist.php
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Check to see whether a user a member of a group
|
||||||
|
*
|
||||||
|
* 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 Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @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 whether a user is a member of a specified group.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @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 ApiGroupListAction extends ApiBareAuthAction
|
||||||
|
{
|
||||||
|
var $groups = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->getTargetUser($id);
|
||||||
|
$this->groups = $this->getGroups();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Show the user's groups
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
if (empty($this->user)) {
|
||||||
|
$this->clientError(_('No such user!'), 404, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sitename = common_config('site', 'name');
|
||||||
|
$title = sprintf(_("%s's groups"), $this->user->nickname);
|
||||||
|
$taguribase = common_config('integration', 'taguri');
|
||||||
|
$id = "tag:$taguribase:Groups";
|
||||||
|
$link = common_local_url(
|
||||||
|
'usergroups',
|
||||||
|
array('nickname' => $this->user->nickname)
|
||||||
|
);
|
||||||
|
$subtitle = sprintf(
|
||||||
|
_("Groups %s is a member of on %s."),
|
||||||
|
$this->user->nickname,
|
||||||
|
$sitename
|
||||||
|
);
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showXmlGroups($this->groups);
|
||||||
|
break;
|
||||||
|
case 'rss':
|
||||||
|
$this->showRssGroups($this->groups, $title, $link, $subtitle);
|
||||||
|
break;
|
||||||
|
case 'atom':
|
||||||
|
$selfuri = common_root_url() . 'api/statusnet/groups/list/' .
|
||||||
|
$this->user->id . '.atom';
|
||||||
|
$this->showAtomGroups(
|
||||||
|
$this->groups,
|
||||||
|
$title,
|
||||||
|
$id,
|
||||||
|
$link,
|
||||||
|
$subtitle,
|
||||||
|
$selfuri
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showJsonGroups($this->groups);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found!'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get groups
|
||||||
|
*
|
||||||
|
* @return array groups
|
||||||
|
*/
|
||||||
|
|
||||||
|
function getGroups()
|
||||||
|
{
|
||||||
|
$groups = array();
|
||||||
|
|
||||||
|
$group = $this->user->getGroups(
|
||||||
|
($this->page - 1) * $this->count,
|
||||||
|
$this->count,
|
||||||
|
$this->since_id,
|
||||||
|
$this->max_id,
|
||||||
|
$this->since
|
||||||
|
);
|
||||||
|
|
||||||
|
while ($group->fetch()) {
|
||||||
|
$groups[] = clone($group);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $groups;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 group the user has joined
|
||||||
|
*/
|
||||||
|
|
||||||
|
function lastModified()
|
||||||
|
{
|
||||||
|
if (!empty($this->groups) && (count($this->groups) > 0)) {
|
||||||
|
return strtotime($this->groups[0]->created);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An entity tag for this list of groups
|
||||||
|
*
|
||||||
|
* Returns an Etag based on the action name, language, user ID and
|
||||||
|
* timestamps of the first and last group the user has joined
|
||||||
|
*
|
||||||
|
* @return string etag
|
||||||
|
*/
|
||||||
|
|
||||||
|
function etag()
|
||||||
|
{
|
||||||
|
if (!empty($this->groups) && (count($this->groups) > 0)) {
|
||||||
|
|
||||||
|
$last = count($this->groups) - 1;
|
||||||
|
|
||||||
|
return '"' . implode(
|
||||||
|
':',
|
||||||
|
array($this->arg('action'),
|
||||||
|
common_language(),
|
||||||
|
$this->user->id,
|
||||||
|
strtotime($this->groups[0]->created),
|
||||||
|
strtotime($this->groups[$last]->created))
|
||||||
|
)
|
||||||
|
. '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
208
actions/apigrouplistall.php
Normal file
208
actions/apigrouplistall.php
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Show the newest groups
|
||||||
|
*
|
||||||
|
* 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 Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @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/api.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns of the lastest 20 groups for the site
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @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 ApiGroupListAllAction extends ApiAction
|
||||||
|
{
|
||||||
|
var $groups = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->getTargetUser($id);
|
||||||
|
$this->groups = $this->getGroups();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Show the user's groups
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
$sitename = common_config('site', 'name');
|
||||||
|
$title = sprintf(_("%s groups"), $sitename);
|
||||||
|
$taguribase = common_config('integration', 'taguri');
|
||||||
|
$id = "tag:$taguribase:Groups";
|
||||||
|
$link = common_local_url('groups');
|
||||||
|
$subtitle = sprintf(_("groups on %s"), $sitename);
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showXmlGroups($this->groups);
|
||||||
|
break;
|
||||||
|
case 'rss':
|
||||||
|
$this->showRssGroups($this->groups, $title, $link, $subtitle);
|
||||||
|
break;
|
||||||
|
case 'atom':
|
||||||
|
$selfuri = common_root_url() .
|
||||||
|
'api/statusnet/groups/list_all.atom';
|
||||||
|
$this->showAtomGroups(
|
||||||
|
$this->groups,
|
||||||
|
$title,
|
||||||
|
$id,
|
||||||
|
$link,
|
||||||
|
$subtitle,
|
||||||
|
$selfuri
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showJsonGroups($this->groups);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found!'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get groups
|
||||||
|
*
|
||||||
|
* @return array groups
|
||||||
|
*/
|
||||||
|
|
||||||
|
function getGroups()
|
||||||
|
{
|
||||||
|
$groups = array();
|
||||||
|
|
||||||
|
// XXX: Use the $page, $count, $max_id, $since_id, and $since parameters
|
||||||
|
|
||||||
|
$group = new User_group();
|
||||||
|
$group->orderBy('created DESC');
|
||||||
|
$group->find();
|
||||||
|
|
||||||
|
while ($group->fetch()) {
|
||||||
|
$groups[] = clone($group);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $groups;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 site's latest group
|
||||||
|
*/
|
||||||
|
|
||||||
|
function lastModified()
|
||||||
|
{
|
||||||
|
if (!empty($this->groups) && (count($this->groups) > 0)) {
|
||||||
|
return strtotime($this->groups[0]->created);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An entity tag for this list of groups
|
||||||
|
*
|
||||||
|
* Returns an Etag based on the action name, language, and
|
||||||
|
* timestamps of the first and last group the user has joined
|
||||||
|
*
|
||||||
|
* @return string etag
|
||||||
|
*/
|
||||||
|
|
||||||
|
function etag()
|
||||||
|
{
|
||||||
|
if (!empty($this->groups) && (count($this->groups) > 0)) {
|
||||||
|
|
||||||
|
$last = count($this->groups) - 1;
|
||||||
|
|
||||||
|
return '"' . implode(
|
||||||
|
':',
|
||||||
|
array($this->arg('action'),
|
||||||
|
common_language(),
|
||||||
|
strtotime($this->groups[0]->created),
|
||||||
|
strtotime($this->groups[$last]->created))
|
||||||
|
)
|
||||||
|
. '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
192
actions/apigroupmembership.php
Normal file
192
actions/apigroupmembership.php
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* List a group's members
|
||||||
|
*
|
||||||
|
* 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 Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @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/api.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List 20 newest members of the group specified by name or ID.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @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 ApiGroupMembershipAction extends ApiAction
|
||||||
|
{
|
||||||
|
var $group = null;
|
||||||
|
var $profiles = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->group = $this->getTargetGroup($this->arg('id'));
|
||||||
|
$this->profiles = $this->getProfiles();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Show the members of the group
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
// XXX: RSS and Atom
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showTwitterXmlUsers($this->profiles);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showJsonUsers($this->profiles);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found!'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch the members of a group
|
||||||
|
*
|
||||||
|
* @return array $profiles list of profiles
|
||||||
|
*/
|
||||||
|
|
||||||
|
function getProfiles()
|
||||||
|
{
|
||||||
|
$profiles = array();
|
||||||
|
|
||||||
|
$profile = $this->group->getMembers(
|
||||||
|
($this->page - 1) * $this->count,
|
||||||
|
$this->count,
|
||||||
|
$this->since_id,
|
||||||
|
$this->max_id,
|
||||||
|
$this->since
|
||||||
|
);
|
||||||
|
|
||||||
|
while ($profile->fetch()) {
|
||||||
|
$profiles[] = clone($profile);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $profiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this action read only?
|
||||||
|
*
|
||||||
|
* @param array $args other arguments
|
||||||
|
*
|
||||||
|
* @return boolean true
|
||||||
|
*/
|
||||||
|
|
||||||
|
function isReadOnly($args)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When was this list of profiles last modified?
|
||||||
|
*
|
||||||
|
* @return string datestamp of the lastest profile in the group
|
||||||
|
*/
|
||||||
|
|
||||||
|
function lastModified()
|
||||||
|
{
|
||||||
|
if (!empty($this->profiles) && (count($this->profiles) > 0)) {
|
||||||
|
return strtotime($this->profiles[0]->created);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An entity tag for this list of groups
|
||||||
|
*
|
||||||
|
* Returns an Etag based on the action name, language
|
||||||
|
* the group id, and timestamps of the first and last
|
||||||
|
* user who has joined the group
|
||||||
|
*
|
||||||
|
* @return string etag
|
||||||
|
*/
|
||||||
|
|
||||||
|
function etag()
|
||||||
|
{
|
||||||
|
if (!empty($this->profiles) && (count($this->profiles) > 0)) {
|
||||||
|
|
||||||
|
$last = count($this->profiles) - 1;
|
||||||
|
|
||||||
|
return '"' . implode(
|
||||||
|
':',
|
||||||
|
array($this->arg('action'),
|
||||||
|
common_language(),
|
||||||
|
$this->group->id,
|
||||||
|
strtotime($this->profiles[0]->created),
|
||||||
|
strtotime($this->profiles[$last]->created))
|
||||||
|
)
|
||||||
|
. '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
152
actions/apigroupshow.php
Normal file
152
actions/apigroupshow.php
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Show information about a group
|
||||||
|
*
|
||||||
|
* 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 Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @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/api.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Outputs detailed information about the group specified by ID
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @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 ApiGroupShowAction extends ApiAction
|
||||||
|
{
|
||||||
|
var $group = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->group = $this->getTargetGroup($this->arg('id'));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Check the format and show the user info
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
if (empty($this->group)) {
|
||||||
|
$this->clientError(
|
||||||
|
'Group not found!',
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->show_single_xml_group($this->group);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showSingleJsonGroup($this->group);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(_('API method not found!'), 404, $this->format);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When was this group last modified?
|
||||||
|
*
|
||||||
|
* @return string datestamp of the latest notice in the stream
|
||||||
|
*/
|
||||||
|
|
||||||
|
function lastModified()
|
||||||
|
{
|
||||||
|
if (!empty($this->group)) {
|
||||||
|
return strtotime($this->group->modified);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An entity tag for this group
|
||||||
|
*
|
||||||
|
* Returns an Etag based on the action name, language, and
|
||||||
|
* timestamps of the notice
|
||||||
|
*
|
||||||
|
* @return string etag
|
||||||
|
*/
|
||||||
|
|
||||||
|
function etag()
|
||||||
|
{
|
||||||
|
if (!empty($this->group)) {
|
||||||
|
|
||||||
|
return '"' . implode(
|
||||||
|
':',
|
||||||
|
array($this->arg('action'),
|
||||||
|
common_language(),
|
||||||
|
$this->group->id,
|
||||||
|
strtotime($this->group->modified))
|
||||||
|
)
|
||||||
|
. '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
96
actions/apihelptest.php
Normal file
96
actions/apihelptest.php
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Test that you can connect to 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 Evan Prodromou <evan@status.net>
|
||||||
|
* @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/api.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the string "ok" in the requested format with a 200 OK HTTP status code.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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 ApiHelpTestAction extends ApiAction
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
if ($this->format == 'xml') {
|
||||||
|
$this->initDocument('xml');
|
||||||
|
$this->element('ok', null, 'true');
|
||||||
|
$this->endDocument('xml');
|
||||||
|
} elseif ($this->format == 'json') {
|
||||||
|
$this->initDocument('json');
|
||||||
|
print '"ok"';
|
||||||
|
$this->endDocument('json');
|
||||||
|
} else {
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found!'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
154
actions/apistatusesdestroy.php
Normal file
154
actions/apistatusesdestroy.php
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
<?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 Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author Tom Blankenship <mac65@mac65.com>
|
||||||
|
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @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 Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author Tom Blankenship <mac65@mac65.com>
|
||||||
|
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @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 $status = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->auth_user;
|
||||||
|
$this->notice_id = (int)$this->trimmed('id');
|
||||||
|
|
||||||
|
if (empty($notice_id)) {
|
||||||
|
$this->notice_id = (int)$this->arg('id');
|
||||||
|
}
|
||||||
|
|
||||||
|
$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->showSingleXmlStatus($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->showSingleXmlStatus($this->notice);
|
||||||
|
} elseif ($this->format == 'json') {
|
||||||
|
$this->show_single_json_status($this->notice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
206
actions/apistatusesshow.php
Normal file
206
actions/apistatusesshow.php
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
<?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 Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author Tom Blankenship <mac65@mac65.com>
|
||||||
|
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @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/api.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the notice specified by id as a Twitter-style status and inline user
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author Tom Blankenship <mac65@mac65.com>
|
||||||
|
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @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 ApiAction
|
||||||
|
{
|
||||||
|
|
||||||
|
var $notice_id = null;
|
||||||
|
var $notice = 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->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->showSingleXmlStatus($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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
241
actions/apistatusesupdate.php
Normal file
241
actions/apistatusesupdate.php
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
<?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 Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author Tom Blankenship <mac65@mac65.com>
|
||||||
|
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @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 Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author Tom Blankenship <mac65@mac65.com>
|
||||||
|
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @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 $source = null;
|
||||||
|
var $status = null;
|
||||||
|
var $in_reply_to_status_id = 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);
|
||||||
|
|
||||||
|
$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->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->showSingleXmlStatus($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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
142
actions/apistatusnetconfig.php
Normal file
142
actions/apistatusnetconfig.php
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Dump of configuration variables
|
||||||
|
*
|
||||||
|
* 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 Evan Prodromou <evan@status.net>
|
||||||
|
* @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/api.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gives a full dump of configuration variables for this instance
|
||||||
|
* of StatusNet, minus variables that may be security-sensitive (like
|
||||||
|
* passwords).
|
||||||
|
* URL: http://identi.ca/api/statusnet/config.(xml|json)
|
||||||
|
* Formats: xml, json
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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 ApiStatusnetConfigAction extends ApiAction
|
||||||
|
{
|
||||||
|
var $keys = array(
|
||||||
|
'site' => array('name', 'server', 'theme', 'path', 'fancy', 'language',
|
||||||
|
'email', 'broughtby', 'broughtbyurl', 'closed',
|
||||||
|
'inviteonly', 'private'),
|
||||||
|
'license' => array('url', 'title', 'image'),
|
||||||
|
'nickname' => array('featured'),
|
||||||
|
'throttle' => array('enabled', 'count', 'timespan'),
|
||||||
|
'xmpp' => array('enabled', 'server', 'user')
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
switch ($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->initDocument('xml');
|
||||||
|
$this->elementStart('config');
|
||||||
|
|
||||||
|
// XXX: check that all sections and settings are legal XML elements
|
||||||
|
|
||||||
|
common_debug(var_export($this->keys, true));
|
||||||
|
|
||||||
|
foreach ($this->keys as $section => $settings) {
|
||||||
|
$this->elementStart($section);
|
||||||
|
foreach ($settings as $setting) {
|
||||||
|
$value = common_config($section, $setting);
|
||||||
|
if (is_array($value)) {
|
||||||
|
$value = implode(',', $value);
|
||||||
|
} else if ($value === false) {
|
||||||
|
$value = 'false';
|
||||||
|
} else if ($value === true) {
|
||||||
|
$value = 'true';
|
||||||
|
}
|
||||||
|
$this->element($setting, null, $value);
|
||||||
|
}
|
||||||
|
$this->elementEnd($section);
|
||||||
|
}
|
||||||
|
$this->elementEnd('config');
|
||||||
|
$this->endDocument('xml');
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$result = array();
|
||||||
|
foreach ($this->keys as $section => $settings) {
|
||||||
|
$result[$section] = array();
|
||||||
|
foreach ($settings as $setting) {
|
||||||
|
$result[$section][$setting]
|
||||||
|
= common_config($section, $setting);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->initDocument('json');
|
||||||
|
$this->showJsonObjects($result);
|
||||||
|
$this->endDocument('json');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found!'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
102
actions/apistatusnetversion.php
Normal file
102
actions/apistatusnetversion.php
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* A version stamp for 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 Evan Prodromou <evan@status.net>
|
||||||
|
* @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/api.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a version number for this version of StatusNet, which
|
||||||
|
* should make things a bit easier for upgrades.
|
||||||
|
* URL: http://identi.ca/api/statusnet/version.(xml|json)
|
||||||
|
* Formats: xml, js
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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 ApiStatusnetVersionAction extends ApiAction
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
switch ($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->initDocument('xml');
|
||||||
|
$this->element('version', null, STATUSNET_VERSION);
|
||||||
|
$this->endDocument('xml');
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->initDocument('json');
|
||||||
|
print '"'.STATUSNET_VERSION.'"';
|
||||||
|
$this->endDocument('json');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found!'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
266
actions/apisubscriptions.php
Normal file
266
actions/apisubscriptions.php
Normal file
@ -0,0 +1,266 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Base class for showing subscription information in the API
|
||||||
|
*
|
||||||
|
* PHP version 5
|
||||||
|
*
|
||||||
|
* LICENCE: This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apibareauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class outputs a list of profiles as Twitter-style user and status objects.
|
||||||
|
* It is used by the API methods /api/statuses/(friends|followers). To support the
|
||||||
|
* social graph methods it also can output a simple list of IDs.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ApiSubscriptionsAction extends ApiBareAuthAction
|
||||||
|
{
|
||||||
|
var $profiles = null;
|
||||||
|
var $tag = null;
|
||||||
|
var $lite = null;
|
||||||
|
var $ids_only = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->tag = $this->arg('tag');
|
||||||
|
|
||||||
|
// Note: Twitter no longer supports 'lite'
|
||||||
|
$this->lite = $this->arg('lite');
|
||||||
|
|
||||||
|
$this->ids_only = $this->arg('ids_only');
|
||||||
|
|
||||||
|
// If called as a social graph method, show 5000 per page, otherwise 100
|
||||||
|
|
||||||
|
$this->count = isset($this->ids_only) ?
|
||||||
|
5000 : (int)$this->arg('count', 100);
|
||||||
|
|
||||||
|
$this->user = $this->getTargetUser($this->arg('id'));
|
||||||
|
|
||||||
|
if (empty($this->user)) {
|
||||||
|
$this->clientError(_('No such user!'), 404, $this->format);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->profiles = $this->getProfiles();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Show the profiles
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
if (!in_array($this->format, array('xml', 'json'))) {
|
||||||
|
$this->clientError(_('API method not found!'), $code = 404);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->initDocument($this->format);
|
||||||
|
|
||||||
|
if (isset($this->ids_only)) {
|
||||||
|
$this->showIds();
|
||||||
|
} else {
|
||||||
|
$this->showProfiles(isset($this->lite) ? false : true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->endDocument($this->format);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get profiles - should get overrrided
|
||||||
|
*
|
||||||
|
* @return array Profiles
|
||||||
|
*/
|
||||||
|
|
||||||
|
function getProfiles()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this action read only?
|
||||||
|
*
|
||||||
|
* @param array $args other arguments
|
||||||
|
*
|
||||||
|
* @return boolean true
|
||||||
|
*/
|
||||||
|
|
||||||
|
function isReadOnly($args)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When was this feed last modified?
|
||||||
|
*
|
||||||
|
* @return string datestamp of the latest profile in the stream
|
||||||
|
*/
|
||||||
|
|
||||||
|
function lastModified()
|
||||||
|
{
|
||||||
|
if (!empty($this->profiles) && (count($this->profiles) > 0)) {
|
||||||
|
return strtotime($this->profiles[0]->created);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An entity tag for this action
|
||||||
|
*
|
||||||
|
* Returns an Etag based on the action name, language, user ID, and
|
||||||
|
* timestamps of the first and last profiles in the subscriptions list
|
||||||
|
* There's also an indicator to show whether this action is being called
|
||||||
|
* as /api/statuses/(friends|followers) or /api/(friends|followers)/ids
|
||||||
|
*
|
||||||
|
* @return string etag
|
||||||
|
*/
|
||||||
|
|
||||||
|
function etag()
|
||||||
|
{
|
||||||
|
if (!empty($this->profiles) && (count($this->profiles) > 0)) {
|
||||||
|
|
||||||
|
$last = count($this->profiles) - 1;
|
||||||
|
|
||||||
|
return '"' . implode(
|
||||||
|
':',
|
||||||
|
array($this->arg('action'),
|
||||||
|
common_language(),
|
||||||
|
$this->user->id,
|
||||||
|
isset($this->ids_only) ? 'IDs' : 'Profiles',
|
||||||
|
strtotime($this->profiles[0]->created),
|
||||||
|
strtotime($this->profiles[$last]->created))
|
||||||
|
)
|
||||||
|
. '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the profiles as Twitter-style useres and statuses
|
||||||
|
*
|
||||||
|
* @param boolean $include_statuses Whether to include the latest status
|
||||||
|
* with each user. Default true.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function showProfiles($include_statuses = true)
|
||||||
|
{
|
||||||
|
switch ($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->elementStart('users', array('type' => 'array'));
|
||||||
|
foreach ($this->profiles as $profile) {
|
||||||
|
$this->showProfile(
|
||||||
|
$profile,
|
||||||
|
$this->format,
|
||||||
|
null,
|
||||||
|
$include_statuses
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$this->elementEnd('users');
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$arrays = array();
|
||||||
|
foreach ($this->profiles as $profile) {
|
||||||
|
$arrays[] = $this->twitterUserArray(
|
||||||
|
$profile,
|
||||||
|
$include_statuses
|
||||||
|
);
|
||||||
|
}
|
||||||
|
print json_encode($arrays);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(_('Unsupported format.'));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the IDs of the profiles only. 5000 per page. To support
|
||||||
|
* the 'social graph' methods: /api/(friends|followers)/ids
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function showIds()
|
||||||
|
{
|
||||||
|
switch ($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->elementStart('ids');
|
||||||
|
foreach ($this->profiles as $profile) {
|
||||||
|
$this->element('id', null, $profile->id);
|
||||||
|
}
|
||||||
|
$this->elementEnd('ids');
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$ids = array();
|
||||||
|
foreach ($this->profiles as $profile) {
|
||||||
|
$ids[] = (int)$profile->id;
|
||||||
|
}
|
||||||
|
print json_encode($ids);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(_('Unsupported format.'));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
237
actions/apitimelinefavorites.php
Normal file
237
actions/apitimelinefavorites.php
Normal file
@ -0,0 +1,237 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Show a user's favorite notices
|
||||||
|
*
|
||||||
|
* 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 Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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 20 most recent favorite notices for the authenticating user or user
|
||||||
|
* specified by the ID parameter in the requested format.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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 ApiTimelineFavoritesAction extends ApiBareAuthAction
|
||||||
|
{
|
||||||
|
var $notices = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$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 / Favorites from %s'),
|
||||||
|
$sitename,
|
||||||
|
$this->user->nickname
|
||||||
|
);
|
||||||
|
|
||||||
|
$taguribase = common_config('integration', 'taguri');
|
||||||
|
$id = "tag:$taguribase:Favorites:" . $this->user->id;
|
||||||
|
$link = common_local_url(
|
||||||
|
'favorites',
|
||||||
|
array('nickname' => $this->user->nickname)
|
||||||
|
);
|
||||||
|
$subtitle = sprintf(
|
||||||
|
_('%s updates favorited by %s / %s.'),
|
||||||
|
$sitename,
|
||||||
|
$profile->getBestName(),
|
||||||
|
$this->user->nickname
|
||||||
|
);
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showXmlTimeline($this->notices);
|
||||||
|
break;
|
||||||
|
case 'rss':
|
||||||
|
$this->showRssTimeline($this->notices, $title, $link, $subtitle);
|
||||||
|
break;
|
||||||
|
case 'atom':
|
||||||
|
$selfuri = common_root_url() .
|
||||||
|
ltrim($_SERVER['QUERY_STRING'], 'p=');
|
||||||
|
$this->showAtomTimeline(
|
||||||
|
$this->notices, $title, $id, $link, $subtitle,
|
||||||
|
null, $selfuri
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showJsonTimeline($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->favoriteNotices(
|
||||||
|
($this->page-1) * $this->count,
|
||||||
|
$this->count,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$notice = $this->user->favoriteNotices(
|
||||||
|
($this->page-1) * $this->count,
|
||||||
|
$this->count,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
247
actions/apitimelinefriends.php
Normal file
247
actions/apitimelinefriends.php
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
<?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 Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author mac65 <mac65@mac65.com>
|
||||||
|
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @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 Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author mac65 <mac65@mac65.com>
|
||||||
|
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @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 $notices = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$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->showXmlTimeline($this->notices);
|
||||||
|
break;
|
||||||
|
case 'rss':
|
||||||
|
$this->showRssTimeline($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->showAtomTimeline(
|
||||||
|
$this->notices, $title, $id, $link,
|
||||||
|
$subtitle, null, $selfuri
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showJsonTimeline($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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
231
actions/apitimelinegroup.php
Normal file
231
actions/apitimelinegroup.php
Normal file
@ -0,0 +1,231 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Show a group's notices
|
||||||
|
*
|
||||||
|
* 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 Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @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/api.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the most recent notices (default 20) posted to the group specified by ID
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @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 ApiTimelineGroupAction extends ApiAction
|
||||||
|
{
|
||||||
|
|
||||||
|
var $group = null;
|
||||||
|
var $notices = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->group = $this->getTargetGroup($this->arg('id'));
|
||||||
|
$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 timeline"), $this->group->nickname);
|
||||||
|
$taguribase = common_config('integration', 'taguri');
|
||||||
|
$id = "tag:$taguribase:GroupTimeline:" . $this->group->id;
|
||||||
|
$link = common_local_url(
|
||||||
|
'showgroup',
|
||||||
|
array('nickname' => $this->group->nickname)
|
||||||
|
);
|
||||||
|
$subtitle = sprintf(
|
||||||
|
_('Updates from %1$s on %2$s!'),
|
||||||
|
$this->group->nickname,
|
||||||
|
$sitename
|
||||||
|
);
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showXmlTimeline($this->notices);
|
||||||
|
break;
|
||||||
|
case 'rss':
|
||||||
|
$this->showRssTimeline($this->notices, $title, $link, $subtitle);
|
||||||
|
break;
|
||||||
|
case 'atom':
|
||||||
|
$selfuri = common_root_url() .
|
||||||
|
'api/statusnet/groups/timeline/' .
|
||||||
|
$this->group->nickname . '.atom';
|
||||||
|
$this->showAtomTimeline(
|
||||||
|
$this->notices,
|
||||||
|
$title,
|
||||||
|
$id,
|
||||||
|
$link,
|
||||||
|
$subtitle,
|
||||||
|
null,
|
||||||
|
$selfuri
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showJsonTimeline($this->notices);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found!'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get notices
|
||||||
|
*
|
||||||
|
* @return array notices
|
||||||
|
*/
|
||||||
|
|
||||||
|
function getNotices()
|
||||||
|
{
|
||||||
|
$notices = array();
|
||||||
|
|
||||||
|
$notice = $this->group->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, group 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->group->id,
|
||||||
|
strtotime($this->notices[0]->created),
|
||||||
|
strtotime($this->notices[$last]->created))
|
||||||
|
)
|
||||||
|
. '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
233
actions/apitimelinementions.php
Normal file
233
actions/apitimelinementions.php
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
<?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 Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author mac65 <mac65@mac65.com>
|
||||||
|
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @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 Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author mac65 <mac65@mac65.com>
|
||||||
|
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @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 $notices = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$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(
|
||||||
|
_('%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->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showXmlTimeline($this->notices);
|
||||||
|
break;
|
||||||
|
case 'rss':
|
||||||
|
$this->showRssTimeline($this->notices, $title, $link, $subtitle);
|
||||||
|
break;
|
||||||
|
case 'atom':
|
||||||
|
$selfuri = common_root_url() .
|
||||||
|
ltrim($_SERVER['QUERY_STRING'], 'p=');
|
||||||
|
$this->showAtomTimeline(
|
||||||
|
$this->notices, $title, $id, $link, $subtitle,
|
||||||
|
null, $selfuri
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showJsonTimeline($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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
213
actions/apitimelinepublic.php
Normal file
213
actions/apitimelinepublic.php
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
<?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 Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author mac65 <mac65@mac65.com>
|
||||||
|
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @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/api.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the most recent notices (default 20) posted by everybody
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author mac65 <mac65@mac65.com>
|
||||||
|
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @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 ApiAction
|
||||||
|
{
|
||||||
|
|
||||||
|
var $notices = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$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->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showXmlTimeline($this->notices);
|
||||||
|
break;
|
||||||
|
case 'rss':
|
||||||
|
$this->showRssTimeline($this->notices, $title, $link, $subtitle);
|
||||||
|
break;
|
||||||
|
case 'atom':
|
||||||
|
$selfuri = common_root_url() . 'api/statuses/public_timeline.atom';
|
||||||
|
$this->showAtomTimeline(
|
||||||
|
$this->notices, $title, $id, $link,
|
||||||
|
$subtitle, null, $selfuri
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showJsonTimeline($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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
224
actions/apitimelinetag.php
Normal file
224
actions/apitimelinetag.php
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Show the latest notices for a given tag
|
||||||
|
*
|
||||||
|
* 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 Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @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/api.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the 20 most recent notices tagged by a given tag
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @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 ApiTimelineTagAction extends ApiAction
|
||||||
|
{
|
||||||
|
|
||||||
|
var $notices = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->tag = $this->arg('tag');
|
||||||
|
$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(_("Notices tagged with %s"), $this->tag);
|
||||||
|
$link = common_local_url(
|
||||||
|
'tag',
|
||||||
|
array('tag' => $this->tag)
|
||||||
|
);
|
||||||
|
$subtitle = sprintf(
|
||||||
|
_('Updates tagged with %1$s on %2$s!'),
|
||||||
|
$this->tag,
|
||||||
|
$sitename
|
||||||
|
);
|
||||||
|
$taguribase = common_config('integration', 'taguri');
|
||||||
|
$id = "tag:$taguribase:TagTimeline:".$tag;
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showXmlTimeline($this->notices);
|
||||||
|
break;
|
||||||
|
case 'rss':
|
||||||
|
$this->showRssTimeline($this->notices, $title, $link, $subtitle);
|
||||||
|
break;
|
||||||
|
case 'atom':
|
||||||
|
$selfuri = common_root_url() .
|
||||||
|
'api/statusnet/tags/timeline/' .
|
||||||
|
$this->tag . '.atom';
|
||||||
|
$this->showAtomTimeline(
|
||||||
|
$this->notices,
|
||||||
|
$title,
|
||||||
|
$id,
|
||||||
|
$link,
|
||||||
|
$subtitle,
|
||||||
|
null,
|
||||||
|
$selfuri
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showJsonTimeline($this->notices);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(_('API method not found!'), $code = 404);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get notices
|
||||||
|
*
|
||||||
|
* @return array notices
|
||||||
|
*/
|
||||||
|
|
||||||
|
function getNotices()
|
||||||
|
{
|
||||||
|
$notices = array();
|
||||||
|
|
||||||
|
$notice = Notice_tag::getStream(
|
||||||
|
$this->tag,
|
||||||
|
($this->page - 1) * $this->count,
|
||||||
|
$this->count + 1
|
||||||
|
);
|
||||||
|
|
||||||
|
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(),
|
||||||
|
$this->tag,
|
||||||
|
strtotime($this->notices[0]->created),
|
||||||
|
strtotime($this->notices[$last]->created))
|
||||||
|
)
|
||||||
|
. '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
248
actions/apitimelineuser.php
Normal file
248
actions/apitimelineuser.php
Normal file
@ -0,0 +1,248 @@
|
|||||||
|
<?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 Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author mac65 <mac65@mac65.com>
|
||||||
|
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @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 Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Jeffery To <jeffery.to@gmail.com>
|
||||||
|
* @author mac65 <mac65@mac65.com>
|
||||||
|
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||||
|
* @author Robin Millette <robin@millette.info>
|
||||||
|
* @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 $notices = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$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 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->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showXmlTimeline($this->notices);
|
||||||
|
break;
|
||||||
|
case 'rss':
|
||||||
|
$this->showRssTimeline(
|
||||||
|
$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->showAtomTimeline(
|
||||||
|
$this->notices, $title, $id, $link,
|
||||||
|
$subtitle, $suplink, $selfuri
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showJsonTimeline($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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
89
actions/apiuserfollowers.php
Normal file
89
actions/apiuserfollowers.php
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
<?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 Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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 Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
89
actions/apiuserfriends.php
Normal file
89
actions/apiuserfriends.php
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
<?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 Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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 Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
126
actions/apiusershow.php
Normal file
126
actions/apiusershow.php
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Show a user's profile information
|
||||||
|
*
|
||||||
|
* 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 Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author mac65 <mac65@mac65.com>
|
||||||
|
* @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/api.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ouputs information for a user, specified by ID or screen name.
|
||||||
|
* The user's most recent status will be returned inline.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author mac65 <mac65@mac65.com>
|
||||||
|
* @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 ApiUserShowAction extends ApiAction
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$email = $this->arg('email');
|
||||||
|
|
||||||
|
// XXX: email field deprecated in Twitter's API
|
||||||
|
|
||||||
|
if (!empty($email)) {
|
||||||
|
$this->user = User::staticGet('email', $email);
|
||||||
|
} else {
|
||||||
|
$this->user = $this->getTargetUser($this->arg('id'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Check the format and show the user info
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
if (empty($this->user)) {
|
||||||
|
$this->clientError(_('Not found.'), 404, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_array($this->format, array('xml', 'json'))) {
|
||||||
|
$this->clientError(_('API method not found!'), $code = 404);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$profile = $this->user->getProfile();
|
||||||
|
|
||||||
|
if (empty($profile)) {
|
||||||
|
$this->clientError(_('User has no profile.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$twitter_user = $this->twitterUserArray($this->user->getProfile(), true);
|
||||||
|
|
||||||
|
if ($this->format == 'xml') {
|
||||||
|
$this->initDocument('xml');
|
||||||
|
$this->showTwitterXmlUser($twitter_user);
|
||||||
|
$this->endDocument('xml');
|
||||||
|
} elseif ($this->format == 'json') {
|
||||||
|
$this->initDocument('json');
|
||||||
|
$this->showJsonObjects($twitter_user);
|
||||||
|
$this->endDocument('json');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,127 +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 TwitapiaccountAction extends TwitterapiAction
|
|
||||||
{
|
|
||||||
function verify_credentials($args, $apidata)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
|
|
||||||
switch ($apidata['content-type']) {
|
|
||||||
case 'xml':
|
|
||||||
case 'json':
|
|
||||||
$action_obj = new TwitapiusersAction();
|
|
||||||
$action_obj->prepare($args);
|
|
||||||
call_user_func(array($action_obj, 'show'), $args, $apidata);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
header('Content-Type: text/html; charset=utf-8');
|
|
||||||
print 'Authorized';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function end_session($args, $apidata)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
$this->serverError(_('API method under construction.'), $code=501);
|
|
||||||
}
|
|
||||||
|
|
||||||
function update_location($args, $apidata)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
|
||||||
$this->clientError(_('This method requires a POST.'),
|
|
||||||
400, $apidata['content-type']);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$location = trim($this->arg('location'));
|
|
||||||
|
|
||||||
if (!is_null($location) && mb_strlen($location) > 255) {
|
|
||||||
|
|
||||||
// XXX: But Twitter just truncates and runs with it. -- Zach
|
|
||||||
$this->clientError(_('That\'s too long. Max notice size is 255 chars.'),
|
|
||||||
406, $apidate['content-type']);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$user = $apidata['user']; // Always the auth user
|
|
||||||
$profile = $user->getProfile();
|
|
||||||
|
|
||||||
$orig_profile = clone($profile);
|
|
||||||
$profile->location = $location;
|
|
||||||
|
|
||||||
$result = $profile->update($orig_profile);
|
|
||||||
|
|
||||||
if (empty($result)) {
|
|
||||||
common_log_db_error($profile, 'UPDATE', __FILE__);
|
|
||||||
$this->serverError(_('Couldn\'t save profile.'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
common_broadcast_profile($profile);
|
|
||||||
$type = $apidata['content-type'];
|
|
||||||
|
|
||||||
$this->init_document($type);
|
|
||||||
$this->show_profile($profile, $type);
|
|
||||||
$this->end_document($type);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function update_delivery_device($args, $apidata)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
$this->serverError(_('API method under construction.'), $code=501);
|
|
||||||
}
|
|
||||||
|
|
||||||
// We don't have a rate limit, but some clients check this method.
|
|
||||||
// It always returns the same thing: 100 hit left.
|
|
||||||
function rate_limit_status($args, $apidata)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
|
|
||||||
$type = $apidata['content-type'];
|
|
||||||
$this->init_document($type);
|
|
||||||
|
|
||||||
if ($apidata['content-type'] == 'xml') {
|
|
||||||
$this->elementStart('hash');
|
|
||||||
$this->element('remaining-hits', array('type' => 'integer'), 100);
|
|
||||||
$this->element('hourly-limit', array('type' => 'integer'), 100);
|
|
||||||
$this->element('reset-time', array('type' => 'datetime'), null);
|
|
||||||
$this->element('reset_time_in_seconds', array('type' => 'integer'), 0);
|
|
||||||
$this->elementEnd('hash');
|
|
||||||
} elseif ($apidata['content-type'] == 'json') {
|
|
||||||
|
|
||||||
$out = array('reset_time_in_seconds' => 0,
|
|
||||||
'remaining_hits' => 100,
|
|
||||||
'hourly_limit' => 100,
|
|
||||||
'reset_time' => '');
|
|
||||||
print json_encode($out);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->end_document($type);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,74 +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 TwitapiblocksAction extends TwitterapiAction
|
|
||||||
{
|
|
||||||
|
|
||||||
function create($args, $apidata)
|
|
||||||
{
|
|
||||||
|
|
||||||
parent::handle($args);
|
|
||||||
|
|
||||||
$blockee = $this->get_user($apidata['api_arg'], $apidata);
|
|
||||||
|
|
||||||
if (empty($blockee)) {
|
|
||||||
$this->clientError('Not Found', 404, $apidata['content-type']);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$user = $apidata['user']; // Always the auth user
|
|
||||||
|
|
||||||
if ($user->hasBlocked($blockee) || $user->block($blockee)) {
|
|
||||||
$type = $apidata['content-type'];
|
|
||||||
$this->init_document($type);
|
|
||||||
$this->show_profile($blockee, $type);
|
|
||||||
$this->end_document($type);
|
|
||||||
} else {
|
|
||||||
$this->serverError(_('Block user failed.'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function destroy($args, $apidata)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
$blockee = $this->get_user($apidata['api_arg'], $apidata);
|
|
||||||
|
|
||||||
if (empty($blockee)) {
|
|
||||||
$this->clientError('Not Found', 404, $apidata['content-type']);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$user = $apidata['user'];
|
|
||||||
|
|
||||||
if (!$user->hasBlocked($blockee) || $user->unblock($blockee)) {
|
|
||||||
$type = $apidata['content-type'];
|
|
||||||
$this->init_document($type);
|
|
||||||
$this->show_profile($blockee, $type);
|
|
||||||
$this->end_document($type);
|
|
||||||
} else {
|
|
||||||
$this->serverError(_('Unblock user failed.'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,305 +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 Twitapidirect_messagesAction extends TwitterapiAction
|
|
||||||
{
|
|
||||||
|
|
||||||
function direct_messages($args, $apidata)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
return $this->show_messages($args, $apidata, 'received');
|
|
||||||
}
|
|
||||||
|
|
||||||
function sent($args, $apidata)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
return $this->show_messages($args, $apidata, 'sent');
|
|
||||||
}
|
|
||||||
|
|
||||||
function show_messages($args, $apidata, $type)
|
|
||||||
{
|
|
||||||
$user = $apidata['user']; // Always the auth user
|
|
||||||
|
|
||||||
$message = new Message();
|
|
||||||
$title = null;
|
|
||||||
$subtitle = null;
|
|
||||||
$link = null;
|
|
||||||
$server = common_root_url();
|
|
||||||
|
|
||||||
if ($type == 'received') {
|
|
||||||
$message->to_profile = $user->id;
|
|
||||||
$title = sprintf(_("Direct messages to %s"), $user->nickname);
|
|
||||||
$subtitle = sprintf(_("All the direct messages sent to %s"),
|
|
||||||
$user->nickname);
|
|
||||||
$link = $server . $user->nickname . '/inbox';
|
|
||||||
} else {
|
|
||||||
$message->from_profile = $user->id;
|
|
||||||
$title = _('Direct Messages You\'ve Sent');
|
|
||||||
$subtitle = sprintf(_("All the direct messages sent from %s"),
|
|
||||||
$user->nickname);
|
|
||||||
$link = $server . $user->nickname . '/outbox';
|
|
||||||
}
|
|
||||||
|
|
||||||
$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 ($max_id) {
|
|
||||||
$message->whereAdd("id <= $max_id");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($since_id) {
|
|
||||||
$message->whereAdd("id > $since_id");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($since) {
|
|
||||||
$d = date('Y-m-d H:i:s', $since);
|
|
||||||
$message->whereAdd("created > '$d'");
|
|
||||||
}
|
|
||||||
|
|
||||||
$message->orderBy('created DESC, id DESC');
|
|
||||||
$message->limit((($page-1)*$count), $count);
|
|
||||||
$message->find();
|
|
||||||
|
|
||||||
switch($apidata['content-type']) {
|
|
||||||
case 'xml':
|
|
||||||
$this->show_xml_dmsgs($message);
|
|
||||||
break;
|
|
||||||
case 'rss':
|
|
||||||
$this->show_rss_dmsgs($message, $title, $link, $subtitle);
|
|
||||||
break;
|
|
||||||
case 'atom':
|
|
||||||
$selfuri = common_root_url() . 'api/direct_messages';
|
|
||||||
$selfuri .= ($type == 'received') ? '.atom' : '/sent.atom';
|
|
||||||
$taguribase = common_config('integration', 'taguri');
|
|
||||||
|
|
||||||
if ($type == 'sent') {
|
|
||||||
$id = "tag:$taguribase:SentDirectMessages:" . $user->id;
|
|
||||||
} else {
|
|
||||||
$id = "tag:$taguribase:DirectMessages:" . $user->id;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->show_atom_dmsgs($message, $title, $link, $subtitle,
|
|
||||||
$selfuri, $id);
|
|
||||||
break;
|
|
||||||
case 'json':
|
|
||||||
$this->show_json_dmsgs($message);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$this->clientError(_('API method not found!'), $code = 404);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// had to change this from "new" to "create" to avoid PHP reserved word
|
|
||||||
function create($args, $apidata)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
|
||||||
$this->clientError(_('This method requires a POST.'),
|
|
||||||
400, $apidata['content-type']);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$user = $apidata['user'];
|
|
||||||
$source = $this->trimmed('source'); // Not supported by Twitter.
|
|
||||||
|
|
||||||
$reserved_sources = array('web', 'omb', 'mail', 'xmpp', 'api');
|
|
||||||
if (empty($source) || in_array($source, $reserved_sources)) {
|
|
||||||
$source = 'api';
|
|
||||||
}
|
|
||||||
|
|
||||||
$content = $this->trimmed('text');
|
|
||||||
|
|
||||||
if (empty($content)) {
|
|
||||||
$this->clientError(_('No message text!'),
|
|
||||||
$code = 406, $apidata['content-type']);
|
|
||||||
} else {
|
|
||||||
$content_shortened = common_shorten_links($content);
|
|
||||||
if (Message::contentTooLong($content_shortened)) {
|
|
||||||
$this->clientError(sprintf(_('That\'s too long. Max message size is %d chars.'),
|
|
||||||
Message::maxContent()),
|
|
||||||
$code = 406, $apidata['content-type']);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$other = $this->get_user($this->trimmed('user'));
|
|
||||||
|
|
||||||
if (empty($other)) {
|
|
||||||
$this->clientError(_('Recipient user not found.'),
|
|
||||||
$code = 403, $apidata['content-type']);
|
|
||||||
return;
|
|
||||||
} else if (!$user->mutuallySubscribed($other)) {
|
|
||||||
$this->clientError(_('Can\'t send direct messages to users who aren\'t your friend.'),
|
|
||||||
$code = 403, $apidata['content-type']);
|
|
||||||
return;
|
|
||||||
} else if ($user->id == $other->id) {
|
|
||||||
// Sending msgs to yourself is allowed by Twitter
|
|
||||||
$this->clientError(_('Don\'t send a message to yourself; just say it to yourself quietly instead.'),
|
|
||||||
$code = 403, $apidata['content-type']);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$message = Message::saveNew($user->id, $other->id,
|
|
||||||
html_entity_decode($content, ENT_NOQUOTES, 'UTF-8'), $source);
|
|
||||||
|
|
||||||
if (is_string($message)) {
|
|
||||||
$this->serverError($message);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->notify($user, $other, $message);
|
|
||||||
|
|
||||||
if ($apidata['content-type'] == 'xml') {
|
|
||||||
$this->show_single_xml_dmsg($message);
|
|
||||||
} elseif ($apidata['content-type'] == 'json') {
|
|
||||||
$this->show_single_json_dmsg($message);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function destroy($args, $apidata)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
$this->serverError(_('API method under construction.'), $code=501);
|
|
||||||
}
|
|
||||||
|
|
||||||
function show_xml_dmsgs($message)
|
|
||||||
{
|
|
||||||
|
|
||||||
$this->init_document('xml');
|
|
||||||
$this->elementStart('direct-messages', array('type' => 'array'));
|
|
||||||
|
|
||||||
if (is_array($message)) {
|
|
||||||
foreach ($message as $m) {
|
|
||||||
$twitter_dm = $this->twitter_dmsg_array($m);
|
|
||||||
$this->show_twitter_xml_dmsg($twitter_dm);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
while ($message->fetch()) {
|
|
||||||
$twitter_dm = $this->twitter_dmsg_array($message);
|
|
||||||
$this->show_twitter_xml_dmsg($twitter_dm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->elementEnd('direct-messages');
|
|
||||||
$this->end_document('xml');
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function show_json_dmsgs($message)
|
|
||||||
{
|
|
||||||
|
|
||||||
$this->init_document('json');
|
|
||||||
|
|
||||||
$dmsgs = array();
|
|
||||||
|
|
||||||
if (is_array($message)) {
|
|
||||||
foreach ($message as $m) {
|
|
||||||
$twitter_dm = $this->twitter_dmsg_array($m);
|
|
||||||
array_push($dmsgs, $twitter_dm);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
while ($message->fetch()) {
|
|
||||||
$twitter_dm = $this->twitter_dmsg_array($message);
|
|
||||||
array_push($dmsgs, $twitter_dm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->show_json_objects($dmsgs);
|
|
||||||
$this->end_document('json');
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function show_rss_dmsgs($message, $title, $link, $subtitle)
|
|
||||||
{
|
|
||||||
|
|
||||||
$this->init_document('rss');
|
|
||||||
|
|
||||||
$this->elementStart('channel');
|
|
||||||
$this->element('title', null, $title);
|
|
||||||
|
|
||||||
$this->element('link', null, $link);
|
|
||||||
$this->element('description', null, $subtitle);
|
|
||||||
$this->element('language', null, 'en-us');
|
|
||||||
$this->element('ttl', null, '40');
|
|
||||||
|
|
||||||
if (is_array($message)) {
|
|
||||||
foreach ($message as $m) {
|
|
||||||
$entry = $this->twitter_rss_dmsg_array($m);
|
|
||||||
$this->show_twitter_rss_item($entry);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
while ($message->fetch()) {
|
|
||||||
$entry = $this->twitter_rss_dmsg_array($message);
|
|
||||||
$this->show_twitter_rss_item($entry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->elementEnd('channel');
|
|
||||||
$this->end_twitter_rss();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function show_atom_dmsgs($message, $title, $link, $subtitle, $selfuri, $id)
|
|
||||||
{
|
|
||||||
|
|
||||||
$this->init_document('atom');
|
|
||||||
|
|
||||||
$this->element('title', null, $title);
|
|
||||||
$this->element('id', null, $id);
|
|
||||||
$this->element('link', array('href' => $link, 'rel' => 'alternate', 'type' => 'text/html'), null);
|
|
||||||
$this->element('link', array('href' => $selfuri, 'rel' => 'self',
|
|
||||||
'type' => 'application/atom+xml'), null);
|
|
||||||
$this->element('updated', null, common_date_iso8601('now'));
|
|
||||||
$this->element('subtitle', null, $subtitle);
|
|
||||||
|
|
||||||
if (is_array($message)) {
|
|
||||||
foreach ($message as $m) {
|
|
||||||
$entry = $this->twitter_rss_dmsg_array($m);
|
|
||||||
$this->show_twitter_atom_entry($entry);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
while ($message->fetch()) {
|
|
||||||
$entry = $this->twitter_rss_dmsg_array($message);
|
|
||||||
$this->show_twitter_atom_entry($entry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->end_document('atom');
|
|
||||||
}
|
|
||||||
|
|
||||||
// swiped from MessageAction. Should it be place in util.php?
|
|
||||||
function notify($from, $to, $message)
|
|
||||||
{
|
|
||||||
mail_notify_message($message, $from, $to);
|
|
||||||
# XXX: Jabber, SMS notifications... probably queued
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,216 +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 TwitapifavoritesAction extends TwitterapiAction
|
|
||||||
{
|
|
||||||
|
|
||||||
function favorites($args, $apidata)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
|
|
||||||
$this->auth_user = $apidata['user'];
|
|
||||||
$user = $this->get_user($apidata['api_arg'], $apidata);
|
|
||||||
|
|
||||||
if (empty($user)) {
|
|
||||||
if ($apidata['content-type'] == 'xml') {
|
|
||||||
$this->show_single_xml_status($notice);
|
|
||||||
} elseif ($apidata['content-type'] == 'json') {
|
|
||||||
$this->show_single_json_status($notice);
|
|
||||||
}
|
|
||||||
$this->clientError('Not Found', 404, $apidata['content-type']);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$profile = $user->getProfile();
|
|
||||||
|
|
||||||
$sitename = common_config('site', 'name');
|
|
||||||
$title = sprintf(_('%s / Favorites from %s'), $sitename,
|
|
||||||
$user->nickname);
|
|
||||||
$taguribase = common_config('integration', 'taguri');
|
|
||||||
$id = "tag:$taguribase:Favorites:".$user->id;
|
|
||||||
$link = common_local_url('favorites',
|
|
||||||
array('nickname' => $user->nickname));
|
|
||||||
$subtitle = sprintf(_('%s updates favorited by %s / %s.'), $sitename,
|
|
||||||
$profile->getBestName(), $user->nickname);
|
|
||||||
|
|
||||||
$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->favoriteNotices(($page-1)*$count, $count, true);
|
|
||||||
} else {
|
|
||||||
$notice = $user->favoriteNotices(($page-1)*$count, $count, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
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 = $selfuri = common_root_url() .
|
|
||||||
'api/favorites/' . $apidata['api_arg'] . '.atom';
|
|
||||||
} else {
|
|
||||||
$selfuri = $selfuri = common_root_url() .
|
|
||||||
'api/favorites.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 create($args, $apidata)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
|
|
||||||
// Check for RESTfulness
|
|
||||||
if (!in_array($_SERVER['REQUEST_METHOD'], array('POST', 'DELETE'))) {
|
|
||||||
$this->clientError(_('This method requires a POST or DELETE.'),
|
|
||||||
400, $apidata['content-type']);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!in_array($apidata['content-type'], array('xml', 'json'))) {
|
|
||||||
$this->clientError(_('API method not found!'), $code = 404);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX: Twitter lets you fave things repeatedly via api.
|
|
||||||
if ($user->hasFave($notice)) {
|
|
||||||
$this->clientError(_('This status is already a favorite!'),
|
|
||||||
403, $apidata['content-type']);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$fave = Fave::addNew($user, $notice);
|
|
||||||
|
|
||||||
if (empty($fave)) {
|
|
||||||
$this->clientError(_('Could not create favorite.'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->notify($fave, $notice, $user);
|
|
||||||
$user->blowFavesCache();
|
|
||||||
|
|
||||||
if ($apidata['content-type'] == 'xml') {
|
|
||||||
$this->show_single_xml_status($notice);
|
|
||||||
} elseif ($apidata['content-type'] == 'json') {
|
|
||||||
$this->show_single_json_status($notice);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function destroy($args, $apidata)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
|
|
||||||
// Check for RESTfulness
|
|
||||||
if (!in_array($_SERVER['REQUEST_METHOD'], array('POST', 'DELETE'))) {
|
|
||||||
$this->clientError(_('This method requires a POST or DELETE.'),
|
|
||||||
400, $apidata['content-type']);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!in_array($apidata['content-type'], array('xml', 'json'))) {
|
|
||||||
$this->clientError(_('API method not found!'), $code = 404);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
$fave = new Fave();
|
|
||||||
$fave->user_id = $this->id;
|
|
||||||
$fave->notice_id = $notice->id;
|
|
||||||
|
|
||||||
if (!$fave->find(true)) {
|
|
||||||
$this->clientError(_('That status is not a favorite!'),
|
|
||||||
403, $apidata['content-type']);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = $fave->delete();
|
|
||||||
|
|
||||||
if (!$result) {
|
|
||||||
common_log_db_error($fave, 'DELETE', __FILE__);
|
|
||||||
$this->clientError(_('Could not delete favorite.'), 404);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$user->blowFavesCache();
|
|
||||||
|
|
||||||
if ($apidata['content-type'] == 'xml') {
|
|
||||||
$this->show_single_xml_status($notice);
|
|
||||||
} elseif ($apidata['content-type'] == 'json') {
|
|
||||||
$this->show_single_json_status($notice);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX: these two funcs swiped from faves.
|
|
||||||
// Maybe put in util.php, or some common base class?
|
|
||||||
|
|
||||||
function notify($fave, $notice, $user)
|
|
||||||
{
|
|
||||||
$other = User::staticGet('id', $notice->profile_id);
|
|
||||||
if ($other && $other->id != $user->id) {
|
|
||||||
if ($other->email && $other->emailnotifyfav) {
|
|
||||||
mail_notify_fave($other, $user, $notice);
|
|
||||||
}
|
|
||||||
# XXX: notify by IM
|
|
||||||
# XXX: notify by SMS
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,250 +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 TwitapifriendshipsAction extends TwitterapiAction
|
|
||||||
{
|
|
||||||
|
|
||||||
function create($args, $apidata)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
|
||||||
$this->clientError(_('This method requires a POST.'),
|
|
||||||
400, $apidata['content-type']);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$id = $apidata['api_arg'];
|
|
||||||
$other = $this->get_user($id);
|
|
||||||
|
|
||||||
if (empty($other)) {
|
|
||||||
$this->clientError(_('Could not follow user: User not found.'),
|
|
||||||
403, $apidata['content-type']);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$user = $apidata['user'];
|
|
||||||
|
|
||||||
if ($user->isSubscribed($other)) {
|
|
||||||
$errmsg = sprintf(_('Could not follow user: %s is already on your list.'),
|
|
||||||
$other->nickname);
|
|
||||||
$this->clientError($errmsg, 403, $apidata['content-type']);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$sub = new Subscription();
|
|
||||||
|
|
||||||
$sub->query('BEGIN');
|
|
||||||
|
|
||||||
$sub->subscriber = $user->id;
|
|
||||||
$sub->subscribed = $other->id;
|
|
||||||
$sub->created = DB_DataObject_Cast::dateTime(); # current time
|
|
||||||
|
|
||||||
$result = $sub->insert();
|
|
||||||
|
|
||||||
if (empty($result)) {
|
|
||||||
$errmsg = sprintf(_('Could not follow user: %s is already on your list.'),
|
|
||||||
$other->nickname);
|
|
||||||
$this->clientError($errmsg, 400, $apidata['content-type']);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$sub->query('COMMIT');
|
|
||||||
|
|
||||||
mail_subscribe_notify($other, $user);
|
|
||||||
|
|
||||||
$type = $apidata['content-type'];
|
|
||||||
$this->init_document($type);
|
|
||||||
$this->show_profile($other, $type);
|
|
||||||
$this->end_document($type);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function destroy($args, $apidata)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
|
|
||||||
if (!in_array($_SERVER['REQUEST_METHOD'], array('POST', 'DELETE'))) {
|
|
||||||
$this->clientError(_('This method requires a POST or DELETE.'),
|
|
||||||
400, $apidata['content-type']);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$id = $apidata['api_arg'];
|
|
||||||
|
|
||||||
# We can't subscribe to a remote person, but we can unsub
|
|
||||||
|
|
||||||
$other = $this->get_profile($id);
|
|
||||||
$user = $apidata['user']; // Alwyas the auth user
|
|
||||||
|
|
||||||
if ($user->id == $other->id) {
|
|
||||||
$this->clientError(_("You cannot unfollow yourself!"),
|
|
||||||
403, $apidata['content-type']);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$sub = new Subscription();
|
|
||||||
$sub->subscriber = $user->id;
|
|
||||||
$sub->subscribed = $other->id;
|
|
||||||
|
|
||||||
if ($sub->find(true)) {
|
|
||||||
$sub->query('BEGIN');
|
|
||||||
$sub->delete();
|
|
||||||
$sub->query('COMMIT');
|
|
||||||
} else {
|
|
||||||
$this->clientError(_('You are not friends with the specified user.'),
|
|
||||||
403, $apidata['content-type']);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$type = $apidata['content-type'];
|
|
||||||
$this->init_document($type);
|
|
||||||
$this->show_profile($other, $type);
|
|
||||||
$this->end_document($type);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function exists($args, $apidata)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
|
|
||||||
if (!in_array($apidata['content-type'], array('xml', 'json'))) {
|
|
||||||
$this->clientError(_('API method not found!'), $code = 404);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$user_a_id = $this->trimmed('user_a');
|
|
||||||
$user_b_id = $this->trimmed('user_b');
|
|
||||||
|
|
||||||
$user_a = $this->get_user($user_a_id);
|
|
||||||
$user_b = $this->get_user($user_b_id);
|
|
||||||
|
|
||||||
if (empty($user_a) || empty($user_b)) {
|
|
||||||
$this->clientError(_('Two user ids or screen_names must be supplied.'),
|
|
||||||
400, $apidata['content-type']);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = $user_a->isSubscribed($user_b);
|
|
||||||
|
|
||||||
switch ($apidata['content-type']) {
|
|
||||||
case 'xml':
|
|
||||||
$this->init_document('xml');
|
|
||||||
$this->element('friends', null, $result);
|
|
||||||
$this->end_document('xml');
|
|
||||||
break;
|
|
||||||
case 'json':
|
|
||||||
$this->init_document('json');
|
|
||||||
print json_encode($result);
|
|
||||||
$this->end_document('json');
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
$source_id = (int)$this->trimmed('source_id');
|
|
||||||
$source_screen_name = $this->trimmed('source_screen_name');
|
|
||||||
|
|
||||||
// If the source is not specified for an unauthenticated request,
|
|
||||||
// the method will return an HTTP 403.
|
|
||||||
|
|
||||||
if (empty($source_id) && empty($source_screen_name)) {
|
|
||||||
if (empty($apidata['user'])) {
|
|
||||||
$this->clientError(_('Could not determine source user.'),
|
|
||||||
$code = 403);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$source = null;
|
|
||||||
|
|
||||||
if (!empty($source_id)) {
|
|
||||||
$source = User::staticGet($source_id);
|
|
||||||
} elseif (!empty($source_screen_name)) {
|
|
||||||
$source = User::staticGet('nickname', $source_screen_name);
|
|
||||||
} else {
|
|
||||||
$source = $apidata['user'];
|
|
||||||
}
|
|
||||||
|
|
||||||
// If a source or target is specified but does not exist,
|
|
||||||
// the method will return an HTTP 404.
|
|
||||||
|
|
||||||
if (empty($source)) {
|
|
||||||
$this->clientError(_('Could not determine source user.'),
|
|
||||||
$code = 404);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$target_id = (int)$this->trimmed('target_id');
|
|
||||||
$target_screen_name = $this->trimmed('target_screen_name');
|
|
||||||
|
|
||||||
$target = null;
|
|
||||||
|
|
||||||
if (!empty($target_id)) {
|
|
||||||
$target = User::staticGet($target_id);
|
|
||||||
} elseif (!empty($target_screen_name)) {
|
|
||||||
$target = User::staticGet('nickname', $target_screen_name);
|
|
||||||
} else {
|
|
||||||
$this->clientError(_('Target user not specified.'),
|
|
||||||
$code = 403);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (empty($target)) {
|
|
||||||
$this->clientError(_('Could not find target user.'),
|
|
||||||
$code = 404);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = $this->twitter_relationship_array($source, $target);
|
|
||||||
|
|
||||||
switch ($apidata['content-type']) {
|
|
||||||
case 'xml':
|
|
||||||
$this->init_document('xml');
|
|
||||||
$this->show_twitter_xml_relationship($result[relationship]);
|
|
||||||
$this->end_document('xml');
|
|
||||||
break;
|
|
||||||
case 'json':
|
|
||||||
$this->init_document('json');
|
|
||||||
print json_encode($result);
|
|
||||||
$this->end_document('json');
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,596 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* StatusNet, the distributed open-source microblogging tool
|
|
||||||
*
|
|
||||||
* StatusNet extensions to the Twitter-like API for groups
|
|
||||||
*
|
|
||||||
* 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 Twitter
|
|
||||||
* @package StatusNet
|
|
||||||
* @author Craig Andrews <candrews@integralblue.com>
|
|
||||||
* @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') && !defined('LACONICA')) {
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once INSTALLDIR.'/lib/twitterapi.php';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Group-specific API methods
|
|
||||||
*
|
|
||||||
* This class handles StatusNet group API methods.
|
|
||||||
*
|
|
||||||
* @category Twitter
|
|
||||||
* @package StatusNet
|
|
||||||
* @author Craig Andrews <candrews@integralblue.com>
|
|
||||||
* @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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
class TwitapigroupsAction extends TwitterapiAction
|
|
||||||
{
|
|
||||||
|
|
||||||
function list_groups($args, $apidata)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
|
|
||||||
common_debug("in groups api action");
|
|
||||||
|
|
||||||
$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;
|
|
||||||
}
|
|
||||||
|
|
||||||
$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');
|
|
||||||
$group = $user->getGroups(($page-1)*$count,
|
|
||||||
$count, $since_id, $max_id, $since);
|
|
||||||
|
|
||||||
$sitename = common_config('site', 'name');
|
|
||||||
$title = sprintf(_("%s's groups"), $user->nickname);
|
|
||||||
$taguribase = common_config('integration', 'taguri');
|
|
||||||
$id = "tag:$taguribase:Groups";
|
|
||||||
$link = common_root_url();
|
|
||||||
$subtitle = sprintf(_("groups %s is a member of on %s"), $user->nickname, $sitename);
|
|
||||||
|
|
||||||
switch($apidata['content-type']) {
|
|
||||||
case 'xml':
|
|
||||||
$this->show_xml_groups($group);
|
|
||||||
break;
|
|
||||||
case 'rss':
|
|
||||||
$this->show_rss_groups($group, $title, $link, $subtitle);
|
|
||||||
break;
|
|
||||||
case 'atom':
|
|
||||||
$selfuri = common_root_url() . 'api/statusnet/groups/list/' . $user->id . '.atom';
|
|
||||||
$this->show_atom_groups($group, $title, $id, $link,
|
|
||||||
$subtitle, $selfuri);
|
|
||||||
break;
|
|
||||||
case 'json':
|
|
||||||
$this->show_json_groups($group);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$this->clientError(_('API method not found!'), $code = 404);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function list_all($args, $apidata)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
|
|
||||||
common_debug("in groups api action");
|
|
||||||
|
|
||||||
$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');
|
|
||||||
|
|
||||||
/* TODO:
|
|
||||||
Use the $page, $count, $max_id, $since_id, and $since parameters
|
|
||||||
*/
|
|
||||||
$group = new User_group();
|
|
||||||
$group->orderBy('created DESC');
|
|
||||||
$group->find();
|
|
||||||
|
|
||||||
$sitename = common_config('site', 'name');
|
|
||||||
$title = sprintf(_("%s groups"), $sitename);
|
|
||||||
$taguribase = common_config('integration', 'taguri');
|
|
||||||
$id = "tag:$taguribase:Groups";
|
|
||||||
$link = common_root_url();
|
|
||||||
$subtitle = sprintf(_("groups on %s"), $sitename);
|
|
||||||
|
|
||||||
switch($apidata['content-type']) {
|
|
||||||
case 'xml':
|
|
||||||
$this->show_xml_groups($group);
|
|
||||||
break;
|
|
||||||
case 'rss':
|
|
||||||
$this->show_rss_groups($group, $title, $link, $subtitle);
|
|
||||||
break;
|
|
||||||
case 'atom':
|
|
||||||
$selfuri = common_root_url() . 'api/statusnet/groups/list_all.atom';
|
|
||||||
$this->show_atom_groups($group, $title, $id, $link,
|
|
||||||
$subtitle, $selfuri);
|
|
||||||
break;
|
|
||||||
case 'json':
|
|
||||||
$this->show_json_groups($group);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$this->clientError(_('API method not found!'), $code = 404);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function show($args, $apidata)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
|
|
||||||
common_debug("in groups api action");
|
|
||||||
|
|
||||||
$this->auth_user = $apidata['user'];
|
|
||||||
$group = $this->get_group($apidata['api_arg'], $apidata);
|
|
||||||
|
|
||||||
if (empty($group)) {
|
|
||||||
$this->clientError('Not Found', 404, $apidata['content-type']);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch($apidata['content-type']) {
|
|
||||||
case 'xml':
|
|
||||||
$this->show_single_xml_group($group);
|
|
||||||
break;
|
|
||||||
case 'json':
|
|
||||||
$this->show_single_json_group($group);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$this->clientError(_('API method not found!'), $code = 404);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function timeline($args, $apidata)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
|
|
||||||
common_debug("in groups api action");
|
|
||||||
|
|
||||||
$this->auth_user = $apidata['user'];
|
|
||||||
$group = $this->get_group($apidata['api_arg'], $apidata);
|
|
||||||
|
|
||||||
if (empty($group)) {
|
|
||||||
$this->clientError('Not Found', 404, $apidata['content-type']);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$sitename = common_config('site', 'name');
|
|
||||||
$title = sprintf(_("%s timeline"), $group->nickname);
|
|
||||||
$taguribase = common_config('integration', 'taguri');
|
|
||||||
$id = "tag:$taguribase:GroupTimeline:".$group->id;
|
|
||||||
$link = common_local_url('showgroup',
|
|
||||||
array('nickname' => $group->nickname));
|
|
||||||
$subtitle = sprintf(_('Updates from %1$s on %2$s!'),
|
|
||||||
$group->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');
|
|
||||||
|
|
||||||
$notice = $group->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);
|
|
||||||
break;
|
|
||||||
case 'atom':
|
|
||||||
if (isset($apidata['api_arg'])) {
|
|
||||||
$selfuri = common_root_url() .
|
|
||||||
'api/statusnet/groups/timeline/' .
|
|
||||||
$apidata['api_arg'] . '.atom';
|
|
||||||
} else {
|
|
||||||
$selfuri = common_root_url() .
|
|
||||||
'api/statusnet/groups/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 membership($args, $apidata)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
|
|
||||||
common_debug("in groups api action");
|
|
||||||
|
|
||||||
$this->auth_user = $apidata['user'];
|
|
||||||
$group = $this->get_group($apidata['api_arg'], $apidata);
|
|
||||||
|
|
||||||
if (empty($group)) {
|
|
||||||
$this->clientError('Not Found', 404, $apidata['content-type']);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$sitename = common_config('site', 'name');
|
|
||||||
$title = sprintf(_("Members of %s group"), $group->nickname);
|
|
||||||
$taguribase = common_config('integration', 'taguri');
|
|
||||||
$id = "tag:$taguribase:GroupMembership:".$group->id;
|
|
||||||
$link = common_local_url('showgroup',
|
|
||||||
array('nickname' => $group->nickname));
|
|
||||||
$subtitle = sprintf(_('Members of %1$s on %2$s'),
|
|
||||||
$group->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');
|
|
||||||
|
|
||||||
$member = $group->getMembers(($page-1)*$count,
|
|
||||||
$count, $since_id, $max_id, $since);
|
|
||||||
|
|
||||||
switch($apidata['content-type']) {
|
|
||||||
case 'xml':
|
|
||||||
$this->show_twitter_xml_users($member);
|
|
||||||
break;
|
|
||||||
//TODO implement the RSS and ATOM content types
|
|
||||||
/*case 'rss':
|
|
||||||
$this->show_rss_users($member, $title, $link, $subtitle);
|
|
||||||
break;*/
|
|
||||||
/*case 'atom':
|
|
||||||
if (isset($apidata['api_arg'])) {
|
|
||||||
$selfuri = common_root_url() .
|
|
||||||
'api/statusnet/groups/membership/' .
|
|
||||||
$apidata['api_arg'] . '.atom';
|
|
||||||
} else {
|
|
||||||
$selfuri = common_root_url() .
|
|
||||||
'api/statusnet/groups/membership.atom';
|
|
||||||
}
|
|
||||||
$this->show_atom_users($member, $title, $id, $link,
|
|
||||||
$subtitle, null, $selfuri);
|
|
||||||
break;*/
|
|
||||||
case 'json':
|
|
||||||
$this->show_json_users($member);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$this->clientError(_('API method not found!'), $code = 404);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function join($args, $apidata)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
|
|
||||||
common_debug("in groups api action");
|
|
||||||
|
|
||||||
$this->auth_user = $apidata['user'];
|
|
||||||
$group = $this->get_group($apidata['api_arg'], $apidata);
|
|
||||||
|
|
||||||
if (empty($group)) {
|
|
||||||
$this->clientError('Not Found', 404, $apidata['content-type']);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if($this->auth_user->isMember($group)){
|
|
||||||
$this->clientError(_('You are already a member of that group'), $code = 403);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Group_block::isBlocked($group, $this->auth_user->getProfile())) {
|
|
||||||
$this->clientError(_('You have been blocked from that group by the admin.'), 403);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$member = new Group_member();
|
|
||||||
|
|
||||||
$member->group_id = $group->id;
|
|
||||||
$member->profile_id = $this->auth_user->id;
|
|
||||||
$member->created = common_sql_now();
|
|
||||||
|
|
||||||
$result = $member->insert();
|
|
||||||
|
|
||||||
if (!$result) {
|
|
||||||
common_log_db_error($member, 'INSERT', __FILE__);
|
|
||||||
$this->serverError(sprintf(_('Could not join user %s to group %s'),
|
|
||||||
$this->auth_user->nickname, $group->nickname));
|
|
||||||
}
|
|
||||||
|
|
||||||
switch($apidata['content-type']) {
|
|
||||||
case 'xml':
|
|
||||||
$this->show_single_xml_group($group);
|
|
||||||
break;
|
|
||||||
case 'json':
|
|
||||||
$this->show_single_json_group($group);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$this->clientError(_('API method not found!'), $code = 404);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function leave($args, $apidata)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
|
|
||||||
common_debug("in groups api action");
|
|
||||||
|
|
||||||
$this->auth_user = $apidata['user'];
|
|
||||||
$group = $this->get_group($apidata['api_arg'], $apidata);
|
|
||||||
|
|
||||||
if (empty($group)) {
|
|
||||||
$this->clientError('Not Found', 404, $apidata['content-type']);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(! $this->auth_user->isMember($group)){
|
|
||||||
$this->clientError(_('You are not a member of that group'), $code = 403);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$member = new Group_member();
|
|
||||||
|
|
||||||
$member->group_id = $group->id;
|
|
||||||
$member->profile_id = $this->auth_user->id;
|
|
||||||
|
|
||||||
if (!$member->find(true)) {
|
|
||||||
$this->serverError(_('Could not find membership record.'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = $member->delete();
|
|
||||||
|
|
||||||
if (!$result) {
|
|
||||||
common_log_db_error($member, 'INSERT', __FILE__);
|
|
||||||
$this->serverError(sprintf(_('Could not remove user %s to group %s'),
|
|
||||||
$this->auth_user->nickname, $group->nickname));
|
|
||||||
}
|
|
||||||
|
|
||||||
switch($apidata['content-type']) {
|
|
||||||
case 'xml':
|
|
||||||
$this->show_single_xml_group($group);
|
|
||||||
break;
|
|
||||||
case 'json':
|
|
||||||
$this->show_single_json_group($group);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$this->clientError(_('API method not found!'), $code = 404);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function is_member($args, $apidata)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
|
|
||||||
common_debug("in groups api action");
|
|
||||||
|
|
||||||
$this->auth_user = $apidata['user'];
|
|
||||||
$group = User_group::staticGet($args['group_id']);
|
|
||||||
if(! $group){
|
|
||||||
$this->clientError(_('Group not found'), $code = 500);
|
|
||||||
}
|
|
||||||
$user = User::staticGet('id', $args['user_id']);
|
|
||||||
if(! $user){
|
|
||||||
$this->clientError(_('User not found'), $code = 500);
|
|
||||||
}
|
|
||||||
|
|
||||||
$is_member=$user->isMember($group);
|
|
||||||
|
|
||||||
switch($apidata['content-type']) {
|
|
||||||
case 'xml':
|
|
||||||
$this->init_document('xml');
|
|
||||||
$this->element('is_member', null, $is_member);
|
|
||||||
$this->end_document('xml');
|
|
||||||
break;
|
|
||||||
case 'json':
|
|
||||||
$this->init_document('json');
|
|
||||||
$this->show_json_objects(array('is_member'=>$is_member));
|
|
||||||
$this->end_document('json');
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$this->clientError(_('API method not found!'), $code = 404);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function create($args, $apidata)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
|
|
||||||
common_debug("in groups api action");
|
|
||||||
if (!common_config('inboxes','enabled')) {
|
|
||||||
$this->serverError(_('Inboxes must be enabled for groups to work'));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->auth_user = $apidata['user'];
|
|
||||||
|
|
||||||
$nickname = $args['nickname'];
|
|
||||||
$fullname = $args['full_name'];
|
|
||||||
$homepage = $args['homepage'];
|
|
||||||
$description = $args['description'];
|
|
||||||
$location = $args['location'];
|
|
||||||
$aliasstring = $args['aliases'];
|
|
||||||
|
|
||||||
if (!Validate::string($nickname, array('min_length' => 1,
|
|
||||||
'max_length' => 64,
|
|
||||||
'format' => NICKNAME_FMT))) {
|
|
||||||
$this->clientError(_('Nickname must have only lowercase letters '.
|
|
||||||
'and numbers and no spaces.'), $code=403);
|
|
||||||
return;
|
|
||||||
} else if ($this->groupNicknameExists($nickname)) {
|
|
||||||
$this->clientError(_('Nickname already in use. Try another one.'), $code=403);
|
|
||||||
return;
|
|
||||||
} else if (!User_group::allowedNickname($nickname)) {
|
|
||||||
$this->clientError(_('Not a valid nickname.'), $code=403);
|
|
||||||
return;
|
|
||||||
} else if (!is_null($homepage) && (strlen($homepage) > 0) &&
|
|
||||||
!Validate::uri($homepage,
|
|
||||||
array('allowed_schemes' =>
|
|
||||||
array('http', 'https')))) {
|
|
||||||
$this->clientError(_('Homepage is not a valid URL.'), $code=403);
|
|
||||||
return;
|
|
||||||
} else if (!is_null($fullname) && mb_strlen($fullname) > 255) {
|
|
||||||
$this->clientError(_('Full name is too long (max 255 chars).'), $code=403);
|
|
||||||
return;
|
|
||||||
} else if (User_group::descriptionTooLong($description)) {
|
|
||||||
$this->clientError(sprintf(_('description is too long (max %d chars).'), User_group::maxDescription()), $code=403);
|
|
||||||
return;
|
|
||||||
} else if (!is_null($location) && mb_strlen($location) > 255) {
|
|
||||||
$this->clientError(_('Location is too long (max 255 chars).'), $code=403);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($aliasstring)) {
|
|
||||||
$aliases = array_map('common_canonical_nickname', array_unique(preg_split('/[\s,]+/', $aliasstring)));
|
|
||||||
} else {
|
|
||||||
$aliases = array();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count($aliases) > common_config('group', 'maxaliases')) {
|
|
||||||
$this->clientError(sprintf(_('Too many aliases! Maximum %d.'),
|
|
||||||
common_config('group', 'maxaliases')), $code=403);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($aliases as $alias) {
|
|
||||||
if (!Validate::string($alias, array('min_length' => 1,
|
|
||||||
'max_length' => 64,
|
|
||||||
'format' => NICKNAME_FMT))) {
|
|
||||||
$this->clientError(sprintf(_('Invalid alias: "%s"'), $alias), $code=403);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ($this->groupNicknameExists($alias)) {
|
|
||||||
$this->clientError(sprintf(_('Alias "%s" already in use. Try another one.'),
|
|
||||||
$alias), $code=403);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// XXX assumes alphanum nicknames
|
|
||||||
if (strcmp($alias, $nickname) == 0) {
|
|
||||||
$this->clientError(_('Alias can\'t be the same as nickname.'), $code=403);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$group = new User_group();
|
|
||||||
|
|
||||||
$group->query('BEGIN');
|
|
||||||
|
|
||||||
$group->nickname = $nickname;
|
|
||||||
$group->fullname = $fullname;
|
|
||||||
$group->homepage = $homepage;
|
|
||||||
$group->description = $description;
|
|
||||||
$group->location = $location;
|
|
||||||
$group->created = common_sql_now();
|
|
||||||
|
|
||||||
$result = $group->insert();
|
|
||||||
|
|
||||||
if (!$result) {
|
|
||||||
common_log_db_error($group, 'INSERT', __FILE__);
|
|
||||||
$this->serverError(_('Could not create group.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = $group->setAliases($aliases);
|
|
||||||
|
|
||||||
if (!$result) {
|
|
||||||
$this->serverError(_('Could not create aliases.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$member = new Group_member();
|
|
||||||
|
|
||||||
$member->group_id = $group->id;
|
|
||||||
$member->profile_id = $this->auth_user->id;
|
|
||||||
$member->is_admin = 1;
|
|
||||||
$member->created = $group->created;
|
|
||||||
|
|
||||||
$result = $member->insert();
|
|
||||||
|
|
||||||
if (!$result) {
|
|
||||||
common_log_db_error($member, 'INSERT', __FILE__);
|
|
||||||
$this->serverError(_('Could not set group membership.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$group->query('COMMIT');
|
|
||||||
|
|
||||||
switch($apidata['content-type']) {
|
|
||||||
case 'xml':
|
|
||||||
$this->show_single_xml_group($group);
|
|
||||||
break;
|
|
||||||
case 'json':
|
|
||||||
$this->show_single_json_group($group);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$this->clientError(_('API method not found!'), $code = 404);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function update($args, $apidata)
|
|
||||||
{
|
|
||||||
die("todo");
|
|
||||||
}
|
|
||||||
|
|
||||||
function update_group_logo($args, $apidata)
|
|
||||||
{
|
|
||||||
die("todo");
|
|
||||||
}
|
|
||||||
|
|
||||||
function destroy($args, $apidata)
|
|
||||||
{
|
|
||||||
die("todo");
|
|
||||||
}
|
|
||||||
|
|
||||||
function tag($args, $apidata)
|
|
||||||
{
|
|
||||||
die("todo");
|
|
||||||
}
|
|
||||||
|
|
||||||
function groupNicknameExists($nickname)
|
|
||||||
{
|
|
||||||
$group = User_group::staticGet('nickname', $nickname);
|
|
||||||
|
|
||||||
if (!empty($group)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
$alias = Group_alias::staticGet('alias', $nickname);
|
|
||||||
|
|
||||||
if (!empty($alias)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,57 +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 TwitapihelpAction extends TwitterapiAction
|
|
||||||
{
|
|
||||||
|
|
||||||
/* Returns the string "ok" in the requested format with a 200 OK HTTP status code.
|
|
||||||
* URL:http://identi.ca/api/help/test.format
|
|
||||||
* Formats: xml, json
|
|
||||||
*/
|
|
||||||
function test($args, $apidata)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
|
|
||||||
if ($apidata['content-type'] == 'xml') {
|
|
||||||
$this->init_document('xml');
|
|
||||||
$this->element('ok', null, 'true');
|
|
||||||
$this->end_document('xml');
|
|
||||||
} elseif ($apidata['content-type'] == 'json') {
|
|
||||||
$this->init_document('json');
|
|
||||||
print '"ok"';
|
|
||||||
$this->end_document('json');
|
|
||||||
} else {
|
|
||||||
$this->clientError(_('API method not found!'), $code=404);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function downtime_schedule($args, $apidata)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
$this->serverError(_('API method under construction.'), $code=501);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,40 +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');
|
|
||||||
|
|
||||||
# This naming convention looks real sick
|
|
||||||
class TwitapinotificationsAction extends TwitterapiAction
|
|
||||||
{
|
|
||||||
|
|
||||||
function follow($args, $apidata)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
$this->serverError(_('API method under construction.'), $code=501);
|
|
||||||
}
|
|
||||||
|
|
||||||
function leave($args, $apidata)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
$this->serverError(_('API method under construction.'), $code=501);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -31,7 +31,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
require_once INSTALLDIR.'/lib/twitterapi.php';
|
require_once INSTALLDIR.'/lib/api.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action for outputting search results in Twitter compatible Atom
|
* Action for outputting search results in Twitter compatible Atom
|
||||||
@ -46,10 +46,10 @@ require_once INSTALLDIR.'/lib/twitterapi.php';
|
|||||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*
|
*
|
||||||
* @see TwitterapiAction
|
* @see ApiAction
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class TwitapisearchatomAction extends TwitterapiAction
|
class TwitapisearchatomAction extends ApiAction
|
||||||
{
|
{
|
||||||
|
|
||||||
var $cnt;
|
var $cnt;
|
||||||
@ -340,7 +340,7 @@ class TwitapisearchatomAction extends TwitterapiAction
|
|||||||
// TODO: Here is where we'd put in a link to an atom feed for threads
|
// TODO: Here is where we'd put in a link to an atom feed for threads
|
||||||
|
|
||||||
$this->element("twitter:source", null,
|
$this->element("twitter:source", null,
|
||||||
htmlentities($this->source_link($notice->source)));
|
htmlentities($this->sourceLink($notice->source)));
|
||||||
|
|
||||||
$this->elementStart('author');
|
$this->elementStart('author');
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
require_once INSTALLDIR.'/lib/twitterapi.php';
|
require_once INSTALLDIR.'/lib/api.php';
|
||||||
require_once INSTALLDIR.'/lib/jsonsearchresultslist.php';
|
require_once INSTALLDIR.'/lib/jsonsearchresultslist.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -42,10 +42,10 @@ require_once INSTALLDIR.'/lib/jsonsearchresultslist.php';
|
|||||||
* @author Zach Copley <zach@status.net>
|
* @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
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
* @see TwitterapiAction
|
* @see ApiAction
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class TwitapisearchjsonAction extends TwitterapiAction
|
class TwitapisearchjsonAction extends ApiAction
|
||||||
{
|
{
|
||||||
var $query;
|
var $query;
|
||||||
var $lang;
|
var $lang;
|
||||||
@ -134,9 +134,9 @@ class TwitapisearchjsonAction extends TwitterapiAction
|
|||||||
|
|
||||||
$results = new JSONSearchResultsList($notice, $q, $this->rpp, $this->page);
|
$results = new JSONSearchResultsList($notice, $q, $this->rpp, $this->page);
|
||||||
|
|
||||||
$this->init_document('json');
|
$this->initDocument('json');
|
||||||
$results->show();
|
$results->show();
|
||||||
$this->end_document('json');
|
$this->endDocument('json');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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= !(array_key_exists('lite', $args) and $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= !(array_key_exists('lite', $args) and $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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,175 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* StatusNet, the distributed open-source microblogging tool
|
|
||||||
*
|
|
||||||
* StatusNet-only extensions to the Twitter-like 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 Twitter
|
|
||||||
* @package StatusNet
|
|
||||||
* @author Evan Prodromou <evan@status.net>
|
|
||||||
* @copyright 2008 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') && !defined('LACONICA')) {
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once INSTALLDIR.'/lib/twitterapi.php';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* StatusNet-specific API methods
|
|
||||||
*
|
|
||||||
* This class handles all /statusnet/ API methods.
|
|
||||||
*
|
|
||||||
* @category Twitter
|
|
||||||
* @package StatusNet
|
|
||||||
* @author Evan Prodromou <evan@status.net>
|
|
||||||
* @copyright 2008 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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
class TwitapistatusnetAction extends TwitterapiAction
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* A version stamp for the API
|
|
||||||
*
|
|
||||||
* Returns a version number for this version of StatusNet, which
|
|
||||||
* should make things a bit easier for upgrades.
|
|
||||||
* URL: http://identi.ca/api/statusnet/version.(xml|json)
|
|
||||||
* Formats: xml, json
|
|
||||||
*
|
|
||||||
* @param array $args Web arguments
|
|
||||||
* @param array $apidata Twitter API data
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
* @see ApiAction::process_command()
|
|
||||||
*/
|
|
||||||
|
|
||||||
function version($args, $apidata)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
switch ($apidata['content-type']) {
|
|
||||||
case 'xml':
|
|
||||||
$this->init_document('xml');
|
|
||||||
$this->element('version', null, STATUSNET_VERSION);
|
|
||||||
$this->end_document('xml');
|
|
||||||
break;
|
|
||||||
case 'json':
|
|
||||||
$this->init_document('json');
|
|
||||||
print '"'.STATUSNET_VERSION.'"';
|
|
||||||
$this->end_document('json');
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$this->clientError(_('API method not found!'), $code=404);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dump of configuration variables
|
|
||||||
*
|
|
||||||
* Gives a full dump of configuration variables for this instance
|
|
||||||
* of StatusNet, minus variables that may be security-sensitive (like
|
|
||||||
* passwords).
|
|
||||||
* URL: http://identi.ca/api/statusnet/config.(xml|json)
|
|
||||||
* Formats: xml, json
|
|
||||||
*
|
|
||||||
* @param array $args Web arguments
|
|
||||||
* @param array $apidata Twitter API data
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
* @see ApiAction::process_command()
|
|
||||||
*/
|
|
||||||
|
|
||||||
function config($args, $apidata)
|
|
||||||
{
|
|
||||||
static $keys = array('site' => array('name', 'server', 'theme', 'path', 'fancy', 'language',
|
|
||||||
'email', 'broughtby', 'broughtbyurl', 'closed',
|
|
||||||
'inviteonly', 'private'),
|
|
||||||
'license' => array('url', 'title', 'image'),
|
|
||||||
'nickname' => array('featured'),
|
|
||||||
'throttle' => array('enabled', 'count', 'timespan'),
|
|
||||||
'xmpp' => array('enabled', 'server', 'user'));
|
|
||||||
|
|
||||||
parent::handle($args);
|
|
||||||
|
|
||||||
switch ($apidata['content-type']) {
|
|
||||||
case 'xml':
|
|
||||||
$this->init_document('xml');
|
|
||||||
$this->elementStart('config');
|
|
||||||
// XXX: check that all sections and settings are legal XML elements
|
|
||||||
foreach ($keys as $section => $settings) {
|
|
||||||
$this->elementStart($section);
|
|
||||||
foreach ($settings as $setting) {
|
|
||||||
$value = common_config($section, $setting);
|
|
||||||
if (is_array($value)) {
|
|
||||||
$value = implode(',', $value);
|
|
||||||
} else if ($value === false) {
|
|
||||||
$value = 'false';
|
|
||||||
} else if ($value === true) {
|
|
||||||
$value = 'true';
|
|
||||||
}
|
|
||||||
$this->element($setting, null, $value);
|
|
||||||
}
|
|
||||||
$this->elementEnd($section);
|
|
||||||
}
|
|
||||||
$this->elementEnd('config');
|
|
||||||
$this->end_document('xml');
|
|
||||||
break;
|
|
||||||
case 'json':
|
|
||||||
$result = array();
|
|
||||||
foreach ($keys as $section => $settings) {
|
|
||||||
$result[$section] = array();
|
|
||||||
foreach ($settings as $setting) {
|
|
||||||
$result[$section][$setting] = common_config($section, $setting);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$this->init_document('json');
|
|
||||||
$this->show_json_objects($result);
|
|
||||||
$this->end_document('json');
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$this->clientError(_('API method not found!'), $code=404);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* WADL description of the API
|
|
||||||
*
|
|
||||||
* Gives a WADL description of the API provided by this version of the
|
|
||||||
* software.
|
|
||||||
*
|
|
||||||
* @param array $args Web arguments
|
|
||||||
* @param array $apidata Twitter API data
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
* @see ApiAction::process_command()
|
|
||||||
*/
|
|
||||||
|
|
||||||
function wadl($args, $apidata)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
$this->serverError(_('API method under construction.'), 501);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,113 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* StatusNet, the distributed open-source microblogging tool
|
|
||||||
*
|
|
||||||
* StatusNet extensions to the Twitter-like API for groups
|
|
||||||
*
|
|
||||||
* 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 Twitter
|
|
||||||
* @package StatusNet
|
|
||||||
* @author Craig Andrews <candrews@integralblue.com>
|
|
||||||
* @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') && !defined('LACONICA')) {
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once INSTALLDIR.'/lib/twitterapi.php';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Group-specific API methods
|
|
||||||
*
|
|
||||||
* This class handles StatusNet group API methods.
|
|
||||||
*
|
|
||||||
* @category Twitter
|
|
||||||
* @package StatusNet
|
|
||||||
* @author Craig Andrews <candrews@integralblue.com>
|
|
||||||
* @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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
class TwitapitagsAction extends TwitterapiAction
|
|
||||||
{
|
|
||||||
|
|
||||||
function timeline($args, $apidata)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
|
|
||||||
common_debug("in tags api action");
|
|
||||||
|
|
||||||
$this->auth_user = $apidata['user'];
|
|
||||||
$tag = $apidata['api_arg'];
|
|
||||||
|
|
||||||
if (empty($tag)) {
|
|
||||||
$this->clientError('Not Found', 404, $apidata['content-type']);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$sitename = common_config('site', 'name');
|
|
||||||
$title = sprintf(_("Notices tagged with %s"), $tag);
|
|
||||||
$taguribase = common_config('integration', 'taguri');
|
|
||||||
$id = "tag:$taguribase:TagTimeline:".$tag;
|
|
||||||
$link = common_local_url('tag',
|
|
||||||
array('tag' => $tag));
|
|
||||||
$subtitle = sprintf(_('Updates tagged with %1$s on %2$s!'),
|
|
||||||
$tag, $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');
|
|
||||||
|
|
||||||
# XXX: support max_id, since_id, and since arguments
|
|
||||||
$notice = Notice_tag::getStream($tag, ($page-1)*$count, $count + 1);
|
|
||||||
|
|
||||||
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/statusnet/tags/timeline/' .
|
|
||||||
$apidata['api_arg'] . '.atom';
|
|
||||||
} else {
|
|
||||||
$selfuri = common_root_url() .
|
|
||||||
'api/statusnet/tags/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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -31,7 +31,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
require_once INSTALLDIR.'/lib/twitterapi.php';
|
require_once INSTALLDIR.'/lib/api.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the top ten queries that are currently trending
|
* Returns the top ten queries that are currently trending
|
||||||
@ -42,10 +42,10 @@ require_once INSTALLDIR.'/lib/twitterapi.php';
|
|||||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*
|
*
|
||||||
* @see TwitterapiAction
|
* @see ApiAction
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class TwitapitrendsAction extends TwitterapiAction
|
class TwitapitrendsAction extends ApiAction
|
||||||
{
|
{
|
||||||
|
|
||||||
var $callback;
|
var $callback;
|
||||||
|
@ -1,80 +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 TwitapiusersAction extends TwitterapiAction
|
|
||||||
{
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
$user = null;
|
|
||||||
$email = $this->arg('email');
|
|
||||||
|
|
||||||
// XXX: email field deprecated in Twitter's API
|
|
||||||
|
|
||||||
if ($email) {
|
|
||||||
$user = User::staticGet('email', $email);
|
|
||||||
} else {
|
|
||||||
$user = $this->get_user($apidata['api_arg'], $apidata);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (empty($user)) {
|
|
||||||
$this->clientError(_('Not found.'), 404, $apidata['content-type']);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$profile = $user->getProfile();
|
|
||||||
|
|
||||||
if (!$profile) {
|
|
||||||
common_server_error(_('User has no profile.'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$twitter_user = $this->twitter_user_array($user->getProfile(), true);
|
|
||||||
|
|
||||||
if ($apidata['content-type'] == 'xml') {
|
|
||||||
$this->init_document('xml');
|
|
||||||
$this->show_twitter_xml_user($twitter_user);
|
|
||||||
$this->end_document('xml');
|
|
||||||
} elseif ($apidata['content-type'] == 'json') {
|
|
||||||
$this->init_document('json');
|
|
||||||
$this->show_json_objects($twitter_user);
|
|
||||||
$this->end_document('json');
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// This is in case 'show' was called via /account/verify_credentials
|
|
||||||
// without a format (xml or json).
|
|
||||||
header('Content-Type: text/html; charset=utf-8');
|
|
||||||
print 'Authorized';
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
203
lib/apiauth.php
Normal file
203
lib/apiauth.php
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Base class for API actions that require authentication
|
||||||
|
*
|
||||||
|
* 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 Adrian Lang <mail@adrianlang.de>
|
||||||
|
* @author Brenda Wallace <shiny@cpan.org>
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author mEDI <medi@milaro.net>
|
||||||
|
* @author Sarven Capadisli <csarven@status.net>
|
||||||
|
* @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/api.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Actions extending this class will require auth
|
||||||
|
*
|
||||||
|
* @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 ApiAuthAction extends ApiAction
|
||||||
|
{
|
||||||
|
|
||||||
|
var $auth_user = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running, and output basic auth header if needed
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
if ($this->requiresAuth()) {
|
||||||
|
$this->checkBasicAuthUser();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does this API resource require authentication?
|
||||||
|
*
|
||||||
|
* @return boolean true
|
||||||
|
*/
|
||||||
|
|
||||||
|
function requiresAuth()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check for a user specified via HTTP basic auth. If there isn't
|
||||||
|
* one, try to get one by outputting the basic auth header.
|
||||||
|
*
|
||||||
|
* @return boolean true or false
|
||||||
|
*/
|
||||||
|
|
||||||
|
function checkBasicAuthUser()
|
||||||
|
{
|
||||||
|
$this->basicAuthProcessHeader();
|
||||||
|
|
||||||
|
$realm = common_config('site', 'name') . ' API';
|
||||||
|
|
||||||
|
if (!isset($this->auth_user)) {
|
||||||
|
header('WWW-Authenticate: Basic realm="' . $realm . '"');
|
||||||
|
|
||||||
|
// show error if the user clicks 'cancel'
|
||||||
|
|
||||||
|
$this->showBasicAuthError();
|
||||||
|
exit;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$nickname = $this->auth_user;
|
||||||
|
$password = $this->auth_pw;
|
||||||
|
$this->auth_user = common_check_user($nickname, $password);
|
||||||
|
|
||||||
|
if (empty($this->auth_user)) {
|
||||||
|
|
||||||
|
// basic authentication failed
|
||||||
|
|
||||||
|
list($proxy, $ip) = common_client_ip();
|
||||||
|
common_log(
|
||||||
|
LOG_WARNING,
|
||||||
|
'Failed API auth attempt, nickname = ' .
|
||||||
|
"$nickname, proxy = $proxy, ip = $ip."
|
||||||
|
);
|
||||||
|
$this->showBasicAuthError();
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the HTTP headers and set the auth user. Decodes HTTP_AUTHORIZATION
|
||||||
|
* param to support basic auth when PHP is running in CGI mode.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function basicAuthProcessHeader()
|
||||||
|
{
|
||||||
|
if (isset($_SERVER['AUTHORIZATION'])
|
||||||
|
|| isset($_SERVER['HTTP_AUTHORIZATION'])
|
||||||
|
) {
|
||||||
|
$authorization_header = isset($_SERVER['HTTP_AUTHORIZATION'])
|
||||||
|
? $_SERVER['HTTP_AUTHORIZATION'] : $_SERVER['AUTHORIZATION'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($_SERVER['PHP_AUTH_USER'])) {
|
||||||
|
$this->auth_user = $_SERVER['PHP_AUTH_USER'];
|
||||||
|
$this->auth_pw = $_SERVER['PHP_AUTH_PW'];
|
||||||
|
} elseif (isset($authorization_header)
|
||||||
|
&& strstr(substr($authorization_header, 0, 5), 'Basic')) {
|
||||||
|
|
||||||
|
// decode the HTTP_AUTHORIZATION header on php-cgi server self
|
||||||
|
// on fcgid server the header name is AUTHORIZATION
|
||||||
|
|
||||||
|
$auth_hash = base64_decode(substr($authorization_header, 6));
|
||||||
|
list($this->auth_user, $this->auth_pw) = explode(':', $auth_hash);
|
||||||
|
|
||||||
|
// set all to null on a empty basic auth request
|
||||||
|
|
||||||
|
if ($this->auth_user == "") {
|
||||||
|
$this->auth_user = null;
|
||||||
|
$this->auth_pw = null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->auth_user = null;
|
||||||
|
$this->auth_pw = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output an authentication error message. Use XML or JSON if one
|
||||||
|
* of those formats is specified, otherwise output plain text
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function showBasicAuthError()
|
||||||
|
{
|
||||||
|
header('HTTP/1.1 401 Unauthorized');
|
||||||
|
$msg = 'Could not authenticate you.';
|
||||||
|
|
||||||
|
if ($this->format == 'xml') {
|
||||||
|
header('Content-Type: application/xml; charset=utf-8');
|
||||||
|
$this->startXML();
|
||||||
|
$this->elementStart('hash');
|
||||||
|
$this->element('error', null, $msg);
|
||||||
|
$this->element('request', null, $_SERVER['REQUEST_URI']);
|
||||||
|
$this->elementEnd('hash');
|
||||||
|
$this->endXML();
|
||||||
|
} elseif ($this->format == 'json') {
|
||||||
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
|
$error_array = array('error' => $msg,
|
||||||
|
'request' => $_SERVER['REQUEST_URI']);
|
||||||
|
print(json_encode($error_array));
|
||||||
|
} else {
|
||||||
|
header('Content-type: text/plain');
|
||||||
|
print "$msg\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
109
lib/apibareauth.php
Normal file
109
lib/apibareauth.php
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Base class for API actions that require "bare auth". Bare auth means
|
||||||
|
* authentication is required only if the action is called without an argument
|
||||||
|
* or query param specifying user id.
|
||||||
|
*
|
||||||
|
* 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 Adrian Lang <mail@adrianlang.de>
|
||||||
|
* @author Brenda Wallace <shiny@cpan.org>
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author mEDI <medi@milaro.net>
|
||||||
|
* @author Sarven Capadisli <csarven@status.net>
|
||||||
|
* @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';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Actions extending this class will require auth unless a target
|
||||||
|
* user ID has been specified
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Adrian Lang <mail@adrianlang.de>
|
||||||
|
* @author Brenda Wallace <shiny@cpan.org>
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author mEDI <medi@milaro.net>
|
||||||
|
* @author Sarven Capadisli <csarven@status.net>
|
||||||
|
* @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 ApiBareAuthAction extends ApiAuthAction
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does this API resource require authentication?
|
||||||
|
*
|
||||||
|
* @return boolean true or false
|
||||||
|
*/
|
||||||
|
|
||||||
|
function requiresAuth()
|
||||||
|
{
|
||||||
|
// If the site is "private", all API methods except statusnet/config
|
||||||
|
// need authentication
|
||||||
|
|
||||||
|
if (common_config('site', 'private')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check whether a user has been specified somehow
|
||||||
|
|
||||||
|
$id = $this->arg('id');
|
||||||
|
$user_id = $this->arg('user_id');
|
||||||
|
$screen_name = $this->arg('screen_name');
|
||||||
|
|
||||||
|
if (empty($id) && empty($user_id) && empty($screen_name)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
367
lib/router.php
367
lib/router.php
@ -270,22 +270,100 @@ class Router
|
|||||||
|
|
||||||
// statuses API
|
// statuses API
|
||||||
|
|
||||||
$m->connect('api/statuses/:method',
|
$m->connect('api/statuses/public_timeline.:format',
|
||||||
array('action' => 'api',
|
array('action' => 'ApiTimelinePublic',
|
||||||
'apiaction' => 'statuses'),
|
'format' => '(xml|json|rss|atom)'));
|
||||||
array('method' => '(public_timeline|home_timeline|friends_timeline|user_timeline|update|replies|mentions|show|friends|followers|featured)(\.(atom|rss|xml|json))?'));
|
|
||||||
|
|
||||||
$m->connect('api/statuses/:method/:argument',
|
$m->connect('api/statuses/friends_timeline.:format',
|
||||||
array('action' => 'api',
|
array('action' => 'ApiTimelineFriends',
|
||||||
'apiaction' => 'statuses'),
|
'format' => '(xml|json|rss|atom)'));
|
||||||
array('method' => '(user_timeline|home_timeline|friends_timeline|replies|mentions|show|destroy|friends|followers)'));
|
|
||||||
|
$m->connect('api/statuses/friends_timeline/:id.:format',
|
||||||
|
array('action' => 'ApiTimelineFriends',
|
||||||
|
'id' => '[a-zA-Z0-9]+',
|
||||||
|
'format' => '(xml|json|rss|atom)'));
|
||||||
|
$m->connect('api/statuses/home_timeline.:format',
|
||||||
|
array('action' => 'ApiTimelineFriends',
|
||||||
|
'format' => '(xml|json|rss|atom)'));
|
||||||
|
|
||||||
|
$m->connect('api/statuses/home_timeline/:id.:format',
|
||||||
|
array('action' => 'ApiTimelineFriends',
|
||||||
|
'id' => '[a-zA-Z0-9]+',
|
||||||
|
'format' => '(xml|json|rss|atom)'));
|
||||||
|
|
||||||
|
$m->connect('api/statuses/user_timeline.:format',
|
||||||
|
array('action' => 'ApiTimelineUser',
|
||||||
|
'format' => '(xml|json|rss|atom)'));
|
||||||
|
|
||||||
|
$m->connect('api/statuses/user_timeline/:id.:format',
|
||||||
|
array('action' => 'ApiTimelineUser',
|
||||||
|
'id' => '[a-zA-Z0-9]+',
|
||||||
|
'format' => '(xml|json|rss|atom)'));
|
||||||
|
|
||||||
|
$m->connect('api/statuses/mentions.:format',
|
||||||
|
array('action' => 'ApiTimelineMentions',
|
||||||
|
'format' => '(xml|json|rss|atom)'));
|
||||||
|
|
||||||
|
$m->connect('api/statuses/mentions/:id.:format',
|
||||||
|
array('action' => 'ApiTimelineMentions',
|
||||||
|
'id' => '[a-zA-Z0-9]+',
|
||||||
|
'format' => '(xml|json|rss|atom)'));
|
||||||
|
|
||||||
|
$m->connect('api/statuses/replies.:format',
|
||||||
|
array('action' => 'ApiTimelineMentions',
|
||||||
|
'format' => '(xml|json|rss|atom)'));
|
||||||
|
|
||||||
|
$m->connect('api/statuses/replies/:id.:format',
|
||||||
|
array('action' => 'ApiTimelineMentions',
|
||||||
|
'id' => '[a-zA-Z0-9]+',
|
||||||
|
'format' => '(xml|json|rss|atom)'));
|
||||||
|
|
||||||
|
$m->connect('api/statuses/friends.:format',
|
||||||
|
array('action' => 'ApiUserFriends',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
|
$m->connect('api/statuses/friends/:id.:format',
|
||||||
|
array('action' => 'ApiUserFriends',
|
||||||
|
'id' => '[a-zA-Z0-9]+',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
|
$m->connect('api/statuses/followers.:format',
|
||||||
|
array('action' => 'ApiUserFollowers',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
|
$m->connect('api/statuses/followers/:id.:format',
|
||||||
|
array('action' => 'ApiUserFollowers',
|
||||||
|
'id' => '[a-zA-Z0-9]+',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
|
$m->connect('api/statuses/show.:format',
|
||||||
|
array('action' => 'ApiStatusesShow',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
|
$m->connect('api/statuses/show/:id.:format',
|
||||||
|
array('action' => 'ApiStatusesShow',
|
||||||
|
'id' => '[0-9]+',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
|
$m->connect('api/statuses/update.:format',
|
||||||
|
array('action' => 'ApiStatusesUpdate',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
|
$m->connect('api/statuses/destroy.:format',
|
||||||
|
array('action' => 'ApiStatusesDestroy',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
|
$m->connect('api/statuses/destroy/:id.:format',
|
||||||
|
array('action' => 'ApiStatusesDestroy',
|
||||||
|
'id' => '[0-9]+',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
// users
|
// users
|
||||||
|
|
||||||
$m->connect('api/users/:method/:argument',
|
$m->connect('api/users/show/:id.:format',
|
||||||
array('action' => 'api',
|
array('action' => 'ApiUserShow',
|
||||||
'apiaction' => 'users'),
|
'id' => '[a-zA-Z0-9]+',
|
||||||
array('method' => 'show(\.(xml|json))?'));
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
$m->connect('api/users/:method',
|
$m->connect('api/users/:method',
|
||||||
array('action' => 'api',
|
array('action' => 'api',
|
||||||
@ -294,93 +372,99 @@ class Router
|
|||||||
|
|
||||||
// direct messages
|
// direct messages
|
||||||
|
|
||||||
foreach (array('xml', 'json') as $e) {
|
|
||||||
$m->connect('api/direct_messages/new.'.$e,
|
|
||||||
array('action' => 'api',
|
|
||||||
'apiaction' => 'direct_messages',
|
|
||||||
'method' => 'create.'.$e));
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (array('xml', 'json', 'rss', 'atom') as $e) {
|
$m->connect('api/direct_messages.:format',
|
||||||
$m->connect('api/direct_messages.'.$e,
|
array('action' => 'ApiDirectMessage',
|
||||||
array('action' => 'api',
|
'format' => '(xml|json|rss|atom)'));
|
||||||
'apiaction' => 'direct_messages',
|
|
||||||
'method' => 'direct_messages.'.$e));
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (array('xml', 'json', 'rss', 'atom') as $e) {
|
$m->connect('api/direct_messages/sent.:format',
|
||||||
$m->connect('api/direct_messages/sent.'.$e,
|
array('action' => 'ApiDirectMessage',
|
||||||
array('action' => 'api',
|
'format' => '(xml|json|rss|atom)',
|
||||||
'apiaction' => 'direct_messages',
|
'sent' => true));
|
||||||
'method' => 'sent.'.$e));
|
|
||||||
}
|
|
||||||
|
|
||||||
$m->connect('api/direct_messages/destroy/:argument',
|
$m->connect('api/direct_messages/new.:format',
|
||||||
array('action' => 'api',
|
array('action' => 'ApiDirectMessageNew',
|
||||||
'apiaction' => 'direct_messages'));
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
// friendships
|
// friendships
|
||||||
|
|
||||||
$m->connect('api/friendships/:method/:argument',
|
$m->connect('api/friendships/show.:format',
|
||||||
array('action' => 'api',
|
array('action' => 'ApiFriendshipsShow',
|
||||||
'apiaction' => 'friendships'),
|
'format' => '(xml|json)'));
|
||||||
array('method' => '(create|destroy)'));
|
|
||||||
|
|
||||||
$m->connect('api/friendships/:method',
|
$m->connect('api/friendships/exists.:format',
|
||||||
array('action' => 'api',
|
array('action' => 'ApiFriendshipsExists',
|
||||||
'apiaction' => 'friendships'),
|
'format' => '(xml|json)'));
|
||||||
array('method' => '(show|exists)(\.(xml|json))'));
|
|
||||||
|
$m->connect('api/friendships/create.:format',
|
||||||
|
array('action' => 'ApiFriendshipsCreate',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
|
$m->connect('api/friendships/destroy.:format',
|
||||||
|
array('action' => 'ApiFriendshipsDestroy',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
|
$m->connect('api/friendships/create/:id.:format',
|
||||||
|
array('action' => 'ApiFriendshipsCreate',
|
||||||
|
'id' => '[a-zA-Z0-9]+',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
|
$m->connect('api/friendships/destroy/:id.:format',
|
||||||
|
array('action' => 'ApiFriendshipsDestroy',
|
||||||
|
'id' => '[a-zA-Z0-9]+',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
// Social graph
|
// Social graph
|
||||||
|
|
||||||
$m->connect('api/friends/ids/:argument',
|
$m->connect('api/friends/ids/:id.:format',
|
||||||
array('action' => 'api',
|
array('action' => 'apiFriends',
|
||||||
'apiaction' => 'statuses',
|
'ids_only' => true));
|
||||||
'method' => 'friendsIDs'));
|
|
||||||
|
|
||||||
foreach (array('xml', 'json') as $e) {
|
$m->connect('api/followers/ids/:id.:format',
|
||||||
$m->connect('api/friends/ids.'.$e,
|
array('action' => 'apiFollowers',
|
||||||
array('action' => 'api',
|
'ids_only' => true));
|
||||||
'apiaction' => 'statuses',
|
|
||||||
'method' => 'friendsIDs.'.$e));
|
|
||||||
}
|
|
||||||
|
|
||||||
$m->connect('api/followers/ids/:argument',
|
$m->connect('api/friends/ids.:format',
|
||||||
array('action' => 'api',
|
array('action' => 'apiFriends',
|
||||||
'apiaction' => 'statuses',
|
'ids_only' => true));
|
||||||
'method' => 'followersIDs'));
|
|
||||||
|
|
||||||
foreach (array('xml', 'json') as $e) {
|
$m->connect('api/followers/ids.:format',
|
||||||
$m->connect('api/followers/ids.'.$e,
|
array('action' => 'apiFollowers',
|
||||||
array('action' => 'api',
|
'ids_only' => true));
|
||||||
'apiaction' => 'statuses',
|
|
||||||
'method' => 'followersIDs.'.$e));
|
|
||||||
}
|
|
||||||
|
|
||||||
// account
|
// account
|
||||||
|
|
||||||
$m->connect('api/account/:method',
|
$m->connect('api/account/verify_credentials.:format',
|
||||||
array('action' => 'api',
|
array('action' => 'ApiAccountVerifyCredentials'));
|
||||||
'apiaction' => 'account'));
|
|
||||||
|
// special case where verify_credentials is called w/out a format
|
||||||
|
|
||||||
|
$m->connect('api/account/verify_credentials',
|
||||||
|
array('action' => 'ApiAccountVerifyCredentials'));
|
||||||
|
|
||||||
|
$m->connect('api/account/rate_limit_status.:format',
|
||||||
|
array('action' => 'ApiAccountRateLimitStatus'));
|
||||||
|
|
||||||
// favorites
|
// favorites
|
||||||
|
|
||||||
$m->connect('api/favorites/:method/:argument',
|
$m->connect('api/favorites.:format',
|
||||||
array('action' => 'api',
|
array('action' => 'ApiTimelineFavorites',
|
||||||
'apiaction' => 'favorites',
|
'format' => '(xml|json|rss|atom)'));
|
||||||
array('method' => '(create|destroy)')));
|
|
||||||
|
|
||||||
$m->connect('api/favorites/:argument',
|
$m->connect('api/favorites/:id.:format',
|
||||||
array('action' => 'api',
|
array('action' => 'ApiTimelineFavorites',
|
||||||
'apiaction' => 'favorites',
|
'id' => '[a-zA-Z0-9]+',
|
||||||
'method' => 'favorites'));
|
'format' => '(xmljson|rss|atom)'));
|
||||||
|
|
||||||
foreach (array('xml', 'json', 'rss', 'atom') as $e) {
|
$m->connect('api/favorites/create/:id.:format',
|
||||||
$m->connect('api/favorites.'.$e,
|
array('action' => 'ApiFavoriteCreate',
|
||||||
array('action' => 'api',
|
'id' => '[a-zA-Z0-9]+',
|
||||||
'apiaction' => 'favorites',
|
'format' => '(xml|json)'));
|
||||||
'method' => 'favorites.'.$e));
|
|
||||||
}
|
$m->connect('api/favorites/destroy/:id.:format',
|
||||||
|
array('action' => 'ApiFavoriteDestroy',
|
||||||
|
'id' => '[a-zA-Z0-9]+',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
// notifications
|
// notifications
|
||||||
|
|
||||||
@ -390,71 +474,112 @@ class Router
|
|||||||
|
|
||||||
// blocks
|
// blocks
|
||||||
|
|
||||||
$m->connect('api/blocks/:method/:argument',
|
$m->connect('api/blocks/create/:id.:format',
|
||||||
array('action' => 'api',
|
array('action' => 'ApiBlockCreate',
|
||||||
'apiaction' => 'blocks'));
|
'id' => '[a-zA-Z0-9]+',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
|
$m->connect('api/blocks/destroy/:id.:format',
|
||||||
|
array('action' => 'ApiBlockDestroy',
|
||||||
|
'id' => '[a-zA-Z0-9]+',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
// help
|
// help
|
||||||
|
|
||||||
$m->connect('api/help/:method',
|
$m->connect('api/help/test.:format',
|
||||||
array('action' => 'api',
|
array('action' => 'ApiHelpTest',
|
||||||
'apiaction' => 'help'));
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
// statusnet
|
// statusnet
|
||||||
|
|
||||||
$m->connect('api/statusnet/:method',
|
$m->connect('api/statusnet/version.:format',
|
||||||
array('action' => 'api',
|
array('action' => 'ApiStatusnetVersion',
|
||||||
'apiaction' => 'statusnet'));
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
|
$m->connect('api/statusnet/config.:format',
|
||||||
|
array('action' => 'ApiStatusnetConfig',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
// For older methods, we provide "laconica" base action
|
// For older methods, we provide "laconica" base action
|
||||||
|
|
||||||
$m->connect('api/laconica/:method',
|
$m->connect('api/laconica/version.:format',
|
||||||
array('action' => 'api',
|
array('action' => 'ApiStatusnetVersion',
|
||||||
'apiaction' => 'statusnet'));
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
|
$m->connect('api/laconica/config.:format',
|
||||||
|
array('action' => 'ApiStatusnetConfig',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
// Groups and tags are newer than 0.8.1 so no backward-compatibility
|
// Groups and tags are newer than 0.8.1 so no backward-compatibility
|
||||||
// necessary
|
// necessary
|
||||||
|
|
||||||
// Groups
|
// Groups
|
||||||
//'list' has to be handled differently, as php will not allow a method to be named 'list'
|
//'list' has to be handled differently, as php will not allow a method to be named 'list'
|
||||||
$m->connect('api/statusnet/groups/list/:argument',
|
|
||||||
array('action' => 'api',
|
|
||||||
'method' => 'list_groups',
|
|
||||||
'apiaction' => 'groups'));
|
|
||||||
|
|
||||||
foreach (array('xml', 'json', 'rss', 'atom') as $e) {
|
$m->connect('api/statusnet/groups/timeline/:id.:format',
|
||||||
$m->connect('api/statusnet/groups/list.' . $e,
|
array('action' => 'ApiTimelineGroup',
|
||||||
array('action' => 'api',
|
'id' => '[a-zA-Z0-9]+',
|
||||||
'method' => 'list_groups.' . $e,
|
'format' => '(xmljson|rss|atom)'));
|
||||||
'apiaction' => 'groups'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$m->connect('api/statusnet/groups/:method',
|
$m->connect('api/statusnet/groups/show.:format',
|
||||||
array('action' => 'api',
|
array('action' => 'ApiGroupShow',
|
||||||
'apiaction' => 'statuses'),
|
'format' => '(xml|json)'));
|
||||||
array('method' => '(list_all|)(\.(atom|rss|xml|json))?'));
|
|
||||||
|
|
||||||
$m->connect('api/statuses/:method/:argument',
|
$m->connect('api/statusnet/groups/show/:id.:format',
|
||||||
array('action' => 'api',
|
array('action' => 'ApiGroupShow',
|
||||||
'apiaction' => 'statuses'),
|
'id' => '[a-zA-Z0-9]+',
|
||||||
array('method' => '(user_timeline|home_timeline|friends_timeline|replies|mentions|show|destroy|friends|followers)'));
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
$m->connect('api/statusnet/groups/:method/:argument',
|
$m->connect('api/statusnet/groups/join.:format',
|
||||||
array('action' => 'api',
|
array('action' => 'ApiGroupJoin',
|
||||||
'apiaction' => 'groups'));
|
'id' => '[a-zA-Z0-9]+',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
$m->connect('api/statusnet/groups/:method',
|
$m->connect('api/statusnet/groups/join/:id.:format',
|
||||||
array('action' => 'api',
|
array('action' => 'ApiGroupJoin',
|
||||||
'apiaction' => 'groups'));
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
|
$m->connect('api/statusnet/groups/leave.:format',
|
||||||
|
array('action' => 'ApiGroupLeave',
|
||||||
|
'id' => '[a-zA-Z0-9]+',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
|
$m->connect('api/statusnet/groups/leave/:id.:format',
|
||||||
|
array('action' => 'ApiGroupLeave',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
|
$m->connect('api/statusnet/groups/is_member.:format',
|
||||||
|
array('action' => 'ApiGroupIsMember',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
|
$m->connect('api/statusnet/groups/list.:format',
|
||||||
|
array('action' => 'ApiGroupList',
|
||||||
|
'format' => '(xml|json|rss|atom)'));
|
||||||
|
|
||||||
|
$m->connect('api/statusnet/groups/list/:id.:format',
|
||||||
|
array('action' => 'ApiGroupList',
|
||||||
|
'id' => '[a-zA-Z0-9]+',
|
||||||
|
'format' => '(xml|json|rss|atom)'));
|
||||||
|
|
||||||
|
$m->connect('api/statusnet/groups/list_all.:format',
|
||||||
|
array('action' => 'ApiGroupListAll',
|
||||||
|
'format' => '(xml|json|rss|atom)'));
|
||||||
|
|
||||||
|
$m->connect('api/statusnet/groups/membership.:format',
|
||||||
|
array('action' => 'ApiGroupMembership',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
|
$m->connect('api/statusnet/groups/membership/:id.:format',
|
||||||
|
array('action' => 'ApiGroupMembership',
|
||||||
|
'id' => '[a-zA-Z0-9]+',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
|
$m->connect('api/statusnet/groups/create.:format',
|
||||||
|
array('action' => 'ApiGroupCreate',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
// Tags
|
// Tags
|
||||||
$m->connect('api/statusnet/tags/:method/:argument',
|
$m->connect('api/statusnet/tags/timeline/:tag.:format',
|
||||||
array('action' => 'api',
|
array('action' => 'ApiTimelineTag',
|
||||||
'apiaction' => 'tags'));
|
'format' => '(xmljson|rss|atom)'));
|
||||||
|
|
||||||
$m->connect('api/statusnet/tags/:method',
|
|
||||||
array('action' => 'api',
|
|
||||||
'apiaction' => 'tags'));
|
|
||||||
|
|
||||||
// search
|
// search
|
||||||
$m->connect('api/search.atom', array('action' => 'twitapisearchatom'));
|
$m->connect('api/search.atom', array('action' => 'twitapisearchatom'));
|
||||||
|
@ -23,7 +23,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
|||||||
|
|
||||||
define('TWITTER_SERVICE', 1); // Twitter is foreign_service ID 1
|
define('TWITTER_SERVICE', 1); // Twitter is foreign_service ID 1
|
||||||
|
|
||||||
function update_twitter_user($twitter_id, $screen_name)
|
function updateTwitter_user($twitter_id, $screen_name)
|
||||||
{
|
{
|
||||||
$uri = 'http://twitter.com/' . $screen_name;
|
$uri = 'http://twitter.com/' . $screen_name;
|
||||||
$fuser = new Foreign_user();
|
$fuser = new Foreign_user();
|
||||||
@ -115,7 +115,7 @@ function save_twitter_user($twitter_id, $screen_name)
|
|||||||
// Only update if Twitter screen name has changed
|
// Only update if Twitter screen name has changed
|
||||||
|
|
||||||
if ($fuser->nickname != $screen_name) {
|
if ($fuser->nickname != $screen_name) {
|
||||||
$result = update_twitter_user($twitter_id, $screen_name);
|
$result = updateTwitter_user($twitter_id, $screen_name);
|
||||||
|
|
||||||
common_debug('Twitter bridge - Updated nickname (and URI) for Twitter user ' .
|
common_debug('Twitter bridge - Updated nickname (and URI) for Twitter user ' .
|
||||||
"$fuser->id to $screen_name, was $fuser->nickname");
|
"$fuser->id to $screen_name, was $fuser->nickname");
|
||||||
|
@ -36,8 +36,14 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
|||||||
*
|
*
|
||||||
* @category Integration
|
* @category Integration
|
||||||
* @package StatusNet
|
* @package StatusNet
|
||||||
* @author Zach Copley <zach@status.net>
|
* @author Adrian Lang <mail@adrianlang.de>
|
||||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
* @author Brenda Wallace <shiny@cpan.org>
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @author Dan Moore <dan@moore.cx>
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author mEDI <medi@milaro.net>
|
||||||
|
* @author Sarven Capadisli <csarven@status.net>
|
||||||
|
* @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/
|
* @link http://status.net/
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -240,13 +240,13 @@ class RealtimePlugin extends Plugin
|
|||||||
// FIXME: this code should be abstracted to a neutral third
|
// FIXME: this code should be abstracted to a neutral third
|
||||||
// party, like Notice::asJson(). I'm not sure of the ethics
|
// party, like Notice::asJson(). I'm not sure of the ethics
|
||||||
// of refactoring from within a plugin, so I'm just abusing
|
// of refactoring from within a plugin, so I'm just abusing
|
||||||
// the TwitterApiAction method. Don't do this unless you're me!
|
// the ApiAction method. Don't do this unless you're me!
|
||||||
|
|
||||||
require_once(INSTALLDIR.'/lib/twitterapi.php');
|
require_once(INSTALLDIR.'/lib/api.php');
|
||||||
|
|
||||||
$act = new TwitterApiAction('/dev/null');
|
$act = new ApiAction('/dev/null');
|
||||||
|
|
||||||
$arr = $act->twitter_status_array($notice, true);
|
$arr = $act->twitterStatusArray($notice, true);
|
||||||
$arr['url'] = $notice->bestUrl();
|
$arr['url'] = $notice->bestUrl();
|
||||||
$arr['html'] = htmlspecialchars($notice->rendered);
|
$arr['html'] = htmlspecialchars($notice->rendered);
|
||||||
$arr['source'] = htmlspecialchars($arr['source']);
|
$arr['source'] = htmlspecialchars($arr['source']);
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Plugin that requires the user to have a validated email address before they can post notices
|
||||||
|
*
|
||||||
|
* 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 Plugin
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Craig Andrews <candrews@integralblue.com>
|
||||||
|
* @copyright 2009 Craig Andrews http://candrews.integralblue.com
|
||||||
|
* @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') && !defined('LACONICA')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
class RequireValidatedEmailPlugin extends Plugin
|
||||||
|
{
|
||||||
|
function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onStartNoticeSave($notice)
|
||||||
|
{
|
||||||
|
$user = User::staticGet('id', $notice->profile_id);
|
||||||
|
if (!empty($user)) { // it's a remote notice
|
||||||
|
if (empty($user->email)) {
|
||||||
|
throw new ClientException(_("You must validate your email address before posting."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user