Twitter lists compatible people tags api
This commit is contained in:
parent
4b8ee81ca9
commit
371e923c37
275
actions/apilist.php
Normal file
275
actions/apilist.php
Normal file
|
@ -0,0 +1,275 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Show, update or delete a list.
|
||||||
|
*
|
||||||
|
* 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 Shashi Gowda <connect2shashi@gmail.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')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apibareauth.php';
|
||||||
|
|
||||||
|
class ApiListAction extends ApiBareAuthAction
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The list in question in the current request
|
||||||
|
*/
|
||||||
|
|
||||||
|
var $list = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this an update request?
|
||||||
|
*/
|
||||||
|
|
||||||
|
var $update = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this a delete request?
|
||||||
|
*/
|
||||||
|
|
||||||
|
var $delete = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the flags for handling the request. Show list if this is a GET
|
||||||
|
* request, update it if it is POST, delete list if method is DELETE
|
||||||
|
* or if method is POST and an argument _method is set to DELETE. Act
|
||||||
|
* like we don't know if the current user has no access to the list.
|
||||||
|
*
|
||||||
|
* Takes parameters:
|
||||||
|
* - user: the user id or nickname
|
||||||
|
* - id: the id of the tag or the tag itself
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->delete = ($_SERVER['REQUEST_METHOD'] == 'DELETE' ||
|
||||||
|
($this->trimmed('_method') == 'DELETE' &&
|
||||||
|
$_SERVER['REQUEST_METHOD'] == 'POST'));
|
||||||
|
|
||||||
|
// update list if method is POST or PUT and $this->delete is not true
|
||||||
|
$this->update = (!$this->delete &&
|
||||||
|
in_array($_SERVER['REQUEST_METHOD'], array('POST', 'PUT')));
|
||||||
|
|
||||||
|
$this->user = $this->getTargetUser($this->arg('user'));
|
||||||
|
$this->list = $this->getTargetList($this->arg('user'), $this->arg('id'));
|
||||||
|
|
||||||
|
if (empty($this->list)) {
|
||||||
|
$this->clientError(_('Not found'), 404, $this->format);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
if($this->delete) {
|
||||||
|
$this->handleDelete();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($this->update) {
|
||||||
|
$this->handlePut();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showSingleXmlList($this->list);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showSingleJsonList($this->list);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found.'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* require authentication if it is a write action or user is ambiguous
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function requiresAuth()
|
||||||
|
{
|
||||||
|
return parent::requiresAuth() ||
|
||||||
|
$this->create || $this->delete;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a list
|
||||||
|
*
|
||||||
|
* @return boolean success
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handlePut()
|
||||||
|
{
|
||||||
|
if($this->auth_user->id != $this->list->tagger) {
|
||||||
|
$this->clientError(
|
||||||
|
_('You can not update lists that don\'t belong to you.'),
|
||||||
|
401,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$new_list = clone($this->list);
|
||||||
|
$new_list->tag = common_canonical_tag($this->arg('name'));
|
||||||
|
$new_list->description = common_canonical_tag($this->arg('description'));
|
||||||
|
$new_list->private = ($this->arg('mode') === 'private') ? true : false;
|
||||||
|
|
||||||
|
$result = $new_list->update($this->list);
|
||||||
|
|
||||||
|
if(!$result) {
|
||||||
|
$this->clientError(
|
||||||
|
_('An error occured.'),
|
||||||
|
503,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showSingleXmlList($new_list);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showSingleJsonList($new_list);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found.'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a list
|
||||||
|
*
|
||||||
|
* @return boolean success
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handleDelete()
|
||||||
|
{
|
||||||
|
if($this->auth_user->id != $this->list->tagger) {
|
||||||
|
$this->clientError(
|
||||||
|
_('You can not delete lists that don\'t belong to you.'),
|
||||||
|
401,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$record = clone($this->list);
|
||||||
|
$this->list->delete();
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showSingleXmlList($record);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showSingleJsonList($record);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found.'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicate that this resource is not read-only.
|
||||||
|
*
|
||||||
|
* @return boolean is_read-only=false
|
||||||
|
*/
|
||||||
|
|
||||||
|
function isReadOnly($args)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When was the list (people tag) last updated?
|
||||||
|
*
|
||||||
|
* @return String time_last_modified
|
||||||
|
*/
|
||||||
|
|
||||||
|
function lastModified()
|
||||||
|
{
|
||||||
|
if(!empty($this->list)) {
|
||||||
|
return strtotime($this->list->modified);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An entity tag for this list
|
||||||
|
*
|
||||||
|
* Returns an Etag based on the action name, language, user ID and
|
||||||
|
* timestamps of the first and last list the user has joined
|
||||||
|
*
|
||||||
|
* @return string etag
|
||||||
|
*/
|
||||||
|
|
||||||
|
function etag()
|
||||||
|
{
|
||||||
|
if (!empty($this->list)) {
|
||||||
|
|
||||||
|
return '"' . implode(
|
||||||
|
':',
|
||||||
|
array($this->arg('action'),
|
||||||
|
common_language(),
|
||||||
|
$this->user->id,
|
||||||
|
strtotime($this->list->created),
|
||||||
|
strtotime($this->list->modified))
|
||||||
|
)
|
||||||
|
. '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
124
actions/apilistmember.php
Normal file
124
actions/apilistmember.php
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* API method to check if a user belongs to a list.
|
||||||
|
*
|
||||||
|
* 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 Shashi Gowda <connect2shashi@gmail.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')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apibareauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action handler for Twitter list_memeber methods
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Shashi Gowda <connect2shashi@gmail.com>
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
* @see ApiBareAuthAction
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ApiListMemberAction extends ApiBareAuthAction
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Set the flags for handling the request. Show the profile if this
|
||||||
|
* is a GET request AND the profile is a member of the list, add a member
|
||||||
|
* if it is a POST, remove the profile from the list if method is DELETE
|
||||||
|
* or if method is POST and an argument _method is set to DELETE. Act
|
||||||
|
* like we don't know if the current user has no access to the list.
|
||||||
|
*
|
||||||
|
* Takes parameters:
|
||||||
|
* - user: the user id or nickname
|
||||||
|
* - list_id: the id of the tag or the tag itself
|
||||||
|
* - id: the id of the member being looked for/added/removed
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->getTargetUser($this->arg('id'));
|
||||||
|
$this->list = $this->getTargetList($this->arg('user'), $this->arg('list_id'));
|
||||||
|
|
||||||
|
if (empty($this->list)) {
|
||||||
|
$this->clientError(_('Not found'), 404, $this->format);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->user)) {
|
||||||
|
$this->clientError(_('No such user'), 404, $this->format);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
$arr = array('tagger' => $this->list->tagger,
|
||||||
|
'tag' => $this->list->tag,
|
||||||
|
'tagged' => $this->user->id);
|
||||||
|
$ptag = Profile_tag::pkeyGet($arr);
|
||||||
|
|
||||||
|
if(empty($ptag)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('The specified user is not a member of this list'),
|
||||||
|
400,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = $this->twitterUserArray($this->user->getProfile(), true);
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showTwitterXmlUser($user, 'user', true);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showSingleJsonUser($user);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found.'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
173
actions/apilistmembers.php
Normal file
173
actions/apilistmembers.php
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* List/add/remove list 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 Shashi Gowda <connect2shashi@gmail.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')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apilistusers.php';
|
||||||
|
|
||||||
|
class ApiListMembersAction extends ApiListUsersAction
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Add a user to a list (tag someone)
|
||||||
|
*
|
||||||
|
* @return boolean success
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handlePost()
|
||||||
|
{
|
||||||
|
if($this->auth_user->id != $this->list->tagger) {
|
||||||
|
$this->clientError(
|
||||||
|
_('You aren\'t allowed to add members to this list'),
|
||||||
|
401,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($this->user === false) {
|
||||||
|
$this->clientError(
|
||||||
|
_('You must specify a member'),
|
||||||
|
400,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = Profile_tag::setTag($this->auth_user->id,
|
||||||
|
$this->user->id, $this->list->tag);
|
||||||
|
|
||||||
|
if(empty($result)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('An error occured.'),
|
||||||
|
500,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showSingleXmlList($this->list);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showSingleJsonList($this->list);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found.'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a user from a list (untag someone)
|
||||||
|
*
|
||||||
|
* @return boolean success
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handleDelete()
|
||||||
|
{
|
||||||
|
if($this->auth_user->id != $this->list->tagger) {
|
||||||
|
$this->clientError(
|
||||||
|
_('You aren\'t allowed to remove members from this list'),
|
||||||
|
401,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($this->user === false) {
|
||||||
|
$this->clientError(
|
||||||
|
_('You must specify a member'),
|
||||||
|
400,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$args = array('tagger' => $this->auth_user->id,
|
||||||
|
'tagged' => $this->user->id,
|
||||||
|
'tag' => $this->list->tag);
|
||||||
|
$ptag = Profile_tag::pkeyGet($args);
|
||||||
|
|
||||||
|
if(empty($ptag)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('The user you are trying to remove from the list is not a member'),
|
||||||
|
400,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $ptag->delete();
|
||||||
|
|
||||||
|
if(empty($result)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('An error occured.'),
|
||||||
|
500,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showSingleXmlList($this->list);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showSingleJsonList($this->list);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found.'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List the members of a list (people tagged)
|
||||||
|
*/
|
||||||
|
|
||||||
|
function getUsers()
|
||||||
|
{
|
||||||
|
$fn = array($this->list, 'getTagged');
|
||||||
|
list($this->users, $this->next_cursor, $this->prev_cursor) =
|
||||||
|
Profile_list::getAtCursor($fn, array(), $this->cursor, 20);
|
||||||
|
}
|
||||||
|
}
|
136
actions/apilistmemberships.php
Normal file
136
actions/apilistmemberships.php
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Get a list of lists a user belongs to. (people tags for 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 Shashi Gowda <connect2shashi@gmail.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')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apibareauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action handler for API method to list lists a user belongs to.
|
||||||
|
* (people tags for a user)
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Shashi Gowda <connect2shashi@gmail.com>
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
* @see ApiBareAuthAction
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ApiListMembershipsAction extends ApiBareAuthAction
|
||||||
|
{
|
||||||
|
var $lists = array();
|
||||||
|
var $cursor = -1;
|
||||||
|
var $next_cursor = 0;
|
||||||
|
var $prev_cursor = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare for running the action
|
||||||
|
* Take arguments for running:s
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->cursor = (int) $this->arg('cursor', -1);
|
||||||
|
$this->user = $this->getTargetUser($this->arg('user'));
|
||||||
|
|
||||||
|
if (empty($this->user)) {
|
||||||
|
$this->clientError(_('No such user.'), 404, $this->format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->getLists();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Show the lists
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showXmlLists($this->lists, $this->next_cursor, $this->prev_cursor);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showJsonLists($this->lists, $this->next_cursor, $this->prev_cursor);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found.'),
|
||||||
|
400,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if read only.
|
||||||
|
*
|
||||||
|
* MAY override
|
||||||
|
*
|
||||||
|
* @param array $args other arguments
|
||||||
|
*
|
||||||
|
* @return boolean is read only action?
|
||||||
|
*/
|
||||||
|
|
||||||
|
function isReadOnly($args)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLists()
|
||||||
|
{
|
||||||
|
$profile = $this->user->getProfile();
|
||||||
|
$fn = array($profile, 'getOtherTags');
|
||||||
|
|
||||||
|
# 20 lists
|
||||||
|
list($this->lists, $this->next_cursor, $this->prev_cursor) =
|
||||||
|
Profile_list::getAtCursor($fn, array($this->auth_user), $this->cursor, 20);
|
||||||
|
}
|
||||||
|
}
|
244
actions/apilists.php
Normal file
244
actions/apilists.php
Normal file
|
@ -0,0 +1,244 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* List existing lists or create a new list.
|
||||||
|
*
|
||||||
|
* 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 Shashi Gowda <connect2shashi@gmail.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')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR . '/lib/apibareauth.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action handler for Twitter list_memeber methods
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Shashi Gowda <connect2shashi@gmail.com>
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
* @see ApiBareAuthAction
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ApiListsAction extends ApiBareAuthAction
|
||||||
|
{
|
||||||
|
var $lists = null;
|
||||||
|
var $cursor = 0;
|
||||||
|
var $next_cursor = 0;
|
||||||
|
var $prev_cursor = 0;
|
||||||
|
var $create = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the flags for handling the request. List lists created by user if this
|
||||||
|
* is a GET request, create a new list if it is a POST request.
|
||||||
|
*
|
||||||
|
* Takes parameters:
|
||||||
|
* - user: the user id or nickname
|
||||||
|
* Parameters for POST request
|
||||||
|
* - name: name of the new list (the people tag itself)
|
||||||
|
* - mode: (optional) mode for the new list private/public
|
||||||
|
* - description: (optional) description for the list
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->create = ($_SERVER['REQUEST_METHOD'] == 'POST');
|
||||||
|
|
||||||
|
if (!$this->create) {
|
||||||
|
|
||||||
|
$this->user = $this->getTargetUser($this->arg('user'));
|
||||||
|
|
||||||
|
if (empty($this->user)) {
|
||||||
|
$this->clientError(_('No such user.'), 404, $this->format);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$this->getLists();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* require authentication if it is a write action or user is ambiguous
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function requiresAuth()
|
||||||
|
{
|
||||||
|
return parent::requiresAuth() ||
|
||||||
|
$this->create || $this->delete;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle request:
|
||||||
|
* Show the lists the user has created if the request method is GET
|
||||||
|
* Create a new list by diferring to handlePost() if it is POST.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
if($this->create) {
|
||||||
|
return $this->handlePost();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showXmlLists($this->lists, $this->next_cursor, $this->prev_cursor);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showJsonLists($this->lists, $this->next_cursor, $this->prev_cursor);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found.'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new list
|
||||||
|
*
|
||||||
|
* @return boolean success
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handlePost()
|
||||||
|
{
|
||||||
|
$name=$this->arg('name');
|
||||||
|
if(empty($name)) {
|
||||||
|
// mimick twitter
|
||||||
|
print _("A list's name can't be blank.");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// twitter creates a new list by appending a number to the end
|
||||||
|
// if the list by the given name already exists
|
||||||
|
// it makes more sense to return the existing list instead
|
||||||
|
|
||||||
|
$private = null;
|
||||||
|
if ($this->arg('mode') === 'public') {
|
||||||
|
$private = false;
|
||||||
|
} else if ($this->arg('mode') === 'private') {
|
||||||
|
$private = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$list = Profile_list::ensureTag($this->auth_user->id,
|
||||||
|
$this->arg('name'),
|
||||||
|
$this->arg('description'),
|
||||||
|
$private);
|
||||||
|
if (empty($list)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showSingleXmlList($list);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showSingleJsonList($list);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found.'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get lists
|
||||||
|
*/
|
||||||
|
|
||||||
|
function getLists()
|
||||||
|
{
|
||||||
|
$cursor = (int) $this->arg('cursor', -1);
|
||||||
|
|
||||||
|
// twitter fixes count at 20
|
||||||
|
// there is no argument named count
|
||||||
|
$count = 20;
|
||||||
|
$profile = $this->user->getProfile();
|
||||||
|
$fn = array($profile, 'getOwnedTags');
|
||||||
|
|
||||||
|
list($this->lists,
|
||||||
|
$this->next_cursor,
|
||||||
|
$this->prev_cursor) = Profile_list::getAtCursor($fn, array($this->auth_user), $cursor, $count);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isReadOnly($args)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function lastModified()
|
||||||
|
{
|
||||||
|
if (!$this->create && !empty($this->lists) && (count($this->lists) > 0)) {
|
||||||
|
return strtotime($this->lists[0]->created);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An entity tag for this list of lists
|
||||||
|
*
|
||||||
|
* Returns an Etag based on the action name, language, user ID and
|
||||||
|
* timestamps of the first and last list the user has joined
|
||||||
|
*
|
||||||
|
* @return string etag
|
||||||
|
*/
|
||||||
|
|
||||||
|
function etag()
|
||||||
|
{
|
||||||
|
if (!$this->create && !empty($this->lists) && (count($this->lists) > 0)) {
|
||||||
|
|
||||||
|
$last = count($this->lists) - 1;
|
||||||
|
|
||||||
|
return '"' . implode(
|
||||||
|
':',
|
||||||
|
array($this->arg('action'),
|
||||||
|
common_language(),
|
||||||
|
$this->user->id,
|
||||||
|
strtotime($this->lists[0]->created),
|
||||||
|
strtotime($this->lists[$last]->created))
|
||||||
|
)
|
||||||
|
. '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
91
actions/apilistsubscriber.php
Normal file
91
actions/apilistsubscriber.php
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Check if a user is subscribed to a list
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* @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';
|
||||||
|
|
||||||
|
class ApiListSubscriberAction extends ApiBareAuthAction
|
||||||
|
{
|
||||||
|
var $list = null;
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->user = $this->getTargetUser($this->arg('id'));
|
||||||
|
$this->list = $this->getTargetList($this->arg('user'), $this->arg('list_id'));
|
||||||
|
|
||||||
|
if (empty($this->list)) {
|
||||||
|
$this->clientError(_('Not found'), 404, $this->format);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->user)) {
|
||||||
|
$this->clientError(_('No such user'), 404, $this->format);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
$arr = array('profile_tag_id' => $this->list->id,
|
||||||
|
'profile_id' => $this->user->id);
|
||||||
|
$sub = Profile_tag_subscription::pkeyGet($arr);
|
||||||
|
|
||||||
|
if(empty($sub)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('The specified user is not a subscriber of this list'),
|
||||||
|
400,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = $this->twitterUserArray($this->user->getProfile(), true);
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showTwitterXmlUser($user, 'user', true);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showSingleJsonUser($user);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found.'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
125
actions/apilistsubscribers.php
Normal file
125
actions/apilistsubscribers.php
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Show/add/remove list 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
|
||||||
|
* @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/apilistusers.php';
|
||||||
|
|
||||||
|
class ApiListSubscribersAction extends ApiListUsersAction
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Subscribe to list
|
||||||
|
*
|
||||||
|
* @return boolean success
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handlePost()
|
||||||
|
{
|
||||||
|
$result = Profile_tag_subscription::add($this->list,
|
||||||
|
$this->auth_user);
|
||||||
|
|
||||||
|
if(empty($result)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('An error occured.'),
|
||||||
|
500,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showSingleXmlList($this->list);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showSingleJsonList($this->list);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found.'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDelete()
|
||||||
|
{
|
||||||
|
$args = array('profile_tag_id' => $this->list->id,
|
||||||
|
'profile_id' => $this->auth_user->id);
|
||||||
|
$ptag = Profile_tag_subscription::pkeyGet($args);
|
||||||
|
|
||||||
|
if(empty($ptag)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('You are not subscribed to this list'),
|
||||||
|
400,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Profile_tag_subscription::remove($this->list, $this->auth_user);
|
||||||
|
|
||||||
|
if(empty($result)) {
|
||||||
|
$this->clientError(
|
||||||
|
_('An error occured.'),
|
||||||
|
500,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showSingleXmlList($this->list);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showSingleJsonList($this->list);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found.'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getUsers()
|
||||||
|
{
|
||||||
|
$fn = array($this->list, 'getSubscribers');
|
||||||
|
list($this->users, $this->next_cursor, $this->prev_cursor) =
|
||||||
|
Profile_list::getAtCursor($fn, array(), $this->cursor, 20);
|
||||||
|
}
|
||||||
|
}
|
126
actions/apilistsubscriptions.php
Normal file
126
actions/apilistsubscriptions.php
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Get a list of lists a user is subscribed to.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* @copyright 2009 StatusNet, Inc.
|
||||||
|
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||||
|
* @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';
|
||||||
|
|
||||||
|
class ApiListSubscriptionsAction extends ApiBareAuthAction
|
||||||
|
{
|
||||||
|
var $lists = array();
|
||||||
|
var $cursor = -1;
|
||||||
|
var $next_cursor = 0;
|
||||||
|
var $prev_cursor = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->cursor = (int) $this->arg('cursor', -1);
|
||||||
|
$this->user = $this->getTargetUser($this->arg('user'));
|
||||||
|
$this->getLists();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Show the lists
|
||||||
|
*
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->showXmlLists($this->lists, $this->next_cursor, $this->prev_cursor);
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->showJsonLists($this->lists, $this->next_cursor, $this->prev_cursor);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found.'),
|
||||||
|
400,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if read only.
|
||||||
|
*
|
||||||
|
* MAY override
|
||||||
|
*
|
||||||
|
* @param array $args other arguments
|
||||||
|
*
|
||||||
|
* @return boolean is read only action?
|
||||||
|
*/
|
||||||
|
|
||||||
|
function isReadOnly($args)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLists()
|
||||||
|
{
|
||||||
|
if(empty($this->user)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$profile = $this->user->getProfile();
|
||||||
|
$fn = array($profile, 'getTagSubscriptions');
|
||||||
|
# 20 lists
|
||||||
|
list($this->lists, $this->next_cursor, $this->prev_cursor) =
|
||||||
|
Profile_list::getAtCursor($fn, array(), $this->cursor, 20);
|
||||||
|
}
|
||||||
|
}
|
266
actions/apitimelinelist.php
Normal file
266
actions/apitimelinelist.php
Normal file
|
@ -0,0 +1,266 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Show a list'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.
|
||||||
|
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||||
|
* @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/apiprivateauth.php';
|
||||||
|
require_once INSTALLDIR . '/lib/atomlistnoticefeed.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the most recent notices (default 20) posted to the list 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 ApiTimelineListAction extends ApiPrivateAuthAction
|
||||||
|
{
|
||||||
|
|
||||||
|
var $list = null;
|
||||||
|
var $notices = array();
|
||||||
|
var $next_cursor = 0;
|
||||||
|
var $prev_cursor = 0;
|
||||||
|
var $cursor = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->cursor = (int) $this->arg('cursor', -1);
|
||||||
|
$this->list = $this->getTargetList($this->arg('user'), $this->arg('id'));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Just show the notices
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
if (empty($this->list)) {
|
||||||
|
$this->clientError(_('List not found.'), 404, $this->format);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->getNotices();
|
||||||
|
$this->showTimeline();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the timeline of notices
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function showTimeline()
|
||||||
|
{
|
||||||
|
// We'll pull common formatting out of this for other formats
|
||||||
|
$atom = new AtomListNoticeFeed($this->list, $this->auth_user);
|
||||||
|
|
||||||
|
$self = $this->getSelfUri();
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->initDocument('xml');
|
||||||
|
$this->elementStart('statuses_list',
|
||||||
|
array('xmlns:statusnet' => 'http://status.net/schema/api/1/'));
|
||||||
|
$this->elementStart('statuses', array('type' => 'array'));
|
||||||
|
|
||||||
|
foreach ($this->notices as $n) {
|
||||||
|
$twitter_status = $this->twitterStatusArray($n);
|
||||||
|
$this->showTwitterXmlStatus($twitter_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->elementEnd('statuses');
|
||||||
|
$this->element('next_cursor', null, $this->next_cursor);
|
||||||
|
$this->element('previous_cursor', null, $this->prev_cursor);
|
||||||
|
$this->elementEnd('statuses_list');
|
||||||
|
$this->endDocument('xml');
|
||||||
|
break;
|
||||||
|
case 'rss':
|
||||||
|
$this->showRssTimeline(
|
||||||
|
$this->notices,
|
||||||
|
$atom->title,
|
||||||
|
$this->list->getUri(),
|
||||||
|
$atom->subtitle,
|
||||||
|
null,
|
||||||
|
$atom->logo,
|
||||||
|
$self
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'atom':
|
||||||
|
|
||||||
|
header('Content-Type: application/atom+xml; charset=utf-8');
|
||||||
|
|
||||||
|
try {
|
||||||
|
$atom->setId($self);
|
||||||
|
$atom->setSelfLink($self);
|
||||||
|
$atom->addEntryFromNotices($this->notices);
|
||||||
|
$this->raw($atom->getString());
|
||||||
|
} catch (Atom10FeedException $e) {
|
||||||
|
$this->serverError(
|
||||||
|
'Could not generate feed for list - ' . $e->getMessage()
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->initDocument('json');
|
||||||
|
|
||||||
|
$statuses = array();
|
||||||
|
foreach ($this->notices as $n) {
|
||||||
|
$twitter_status = $this->twitterStatusArray($n);
|
||||||
|
array_push($statuses, $twitter_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
$statuses_list = array('statuses' => $statuses,
|
||||||
|
'next_cursor' => $this->next_cusror,
|
||||||
|
'next_cursor_str' => strval($this->next_cusror),
|
||||||
|
'previous_cursor' => $this->prev_cusror,
|
||||||
|
'previous_cursor_str' => strval($this->prev_cusror)
|
||||||
|
);
|
||||||
|
$this->showJsonObjects($statuses_list);
|
||||||
|
|
||||||
|
$this->initDocument('json');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found.'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get notices
|
||||||
|
*
|
||||||
|
* @return array notices
|
||||||
|
*/
|
||||||
|
|
||||||
|
function getNotices()
|
||||||
|
{
|
||||||
|
$fn = array($this->list, 'getNotices');
|
||||||
|
list($this->notices, $this->next_cursor, $this->prev_cursor) =
|
||||||
|
Profile_list::getAtCursor($fn, array(), $this->cursor, 20);
|
||||||
|
if (!$this->notices) {
|
||||||
|
$this->notices = array();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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, list 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->list->id,
|
||||||
|
strtotime($this->notices[0]->created),
|
||||||
|
strtotime($this->notices[$last]->created))
|
||||||
|
)
|
||||||
|
. '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -64,6 +64,7 @@ class ActivityObject
|
||||||
const BOOKMARK = 'http://activitystrea.ms/schema/1.0/bookmark';
|
const BOOKMARK = 'http://activitystrea.ms/schema/1.0/bookmark';
|
||||||
const PERSON = 'http://activitystrea.ms/schema/1.0/person';
|
const PERSON = 'http://activitystrea.ms/schema/1.0/person';
|
||||||
const GROUP = 'http://activitystrea.ms/schema/1.0/group';
|
const GROUP = 'http://activitystrea.ms/schema/1.0/group';
|
||||||
|
const _LIST = 'http://activitystrea.ms/schema/1.0/list'; // LIST is reserved
|
||||||
const PLACE = 'http://activitystrea.ms/schema/1.0/place';
|
const PLACE = 'http://activitystrea.ms/schema/1.0/place';
|
||||||
const COMMENT = 'http://activitystrea.ms/schema/1.0/comment';
|
const COMMENT = 'http://activitystrea.ms/schema/1.0/comment';
|
||||||
// ^^^^^^^^^^ tea!
|
// ^^^^^^^^^^ tea!
|
||||||
|
@ -92,6 +93,7 @@ class ActivityObject
|
||||||
public $title;
|
public $title;
|
||||||
public $summary;
|
public $summary;
|
||||||
public $content;
|
public $content;
|
||||||
|
public $owner;
|
||||||
public $link;
|
public $link;
|
||||||
public $source;
|
public $source;
|
||||||
public $avatarLinks = array();
|
public $avatarLinks = array();
|
||||||
|
@ -168,6 +170,10 @@ class ActivityObject
|
||||||
Activity::MEDIA
|
Activity::MEDIA
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if ($this->type == self::_LIST) {
|
||||||
|
$owner = ActivityUtils::child($this->element, Activity::AUTHOR, Activity::SPEC);
|
||||||
|
$this->owner = new ActivityObject($owner);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function _fromAuthor($element)
|
private function _fromAuthor($element)
|
||||||
|
@ -520,13 +526,29 @@ class ActivityObject
|
||||||
AVATAR_MINI_SIZE);
|
AVATAR_MINI_SIZE);
|
||||||
|
|
||||||
$object->poco = PoCo::fromGroup($group);
|
$object->poco = PoCo::fromGroup($group);
|
||||||
|
|
||||||
Event::handle('EndActivityObjectFromGroup', array($group, &$object));
|
Event::handle('EndActivityObjectFromGroup', array($group, &$object));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $object;
|
return $object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static function fromPeopletag($ptag)
|
||||||
|
{
|
||||||
|
$object = new ActivityObject();
|
||||||
|
if (Event::handle('StartActivityObjectFromPeopletag', array($ptag, &$object))) {
|
||||||
|
$object->type = ActivityObject::_LIST;
|
||||||
|
|
||||||
|
$object->id = $ptag->getUri();
|
||||||
|
$object->title = $ptag->tag;
|
||||||
|
$object->summary = $ptag->description;
|
||||||
|
$object->link = $ptag->homeUrl();
|
||||||
|
$object->owner = Profile::staticGet('id', $ptag->tagger);
|
||||||
|
$object->poco = PoCo::fromProfile($object->owner);
|
||||||
|
Event::handle('EndActivityObjectFromPeopletag', array($ptag, &$object));
|
||||||
|
}
|
||||||
|
return $object;
|
||||||
|
}
|
||||||
|
|
||||||
function outputTo($xo, $tag='activity:object')
|
function outputTo($xo, $tag='activity:object')
|
||||||
{
|
{
|
||||||
if (!empty($tag)) {
|
if (!empty($tag)) {
|
||||||
|
@ -601,6 +623,11 @@ class ActivityObject
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!empty($this->owner)) {
|
||||||
|
$owner = $this->owner->asActivityNoun(self::AUTHOR);
|
||||||
|
$xo->raw($owner);
|
||||||
|
}
|
||||||
|
|
||||||
if (!empty($this->geopoint)) {
|
if (!empty($this->geopoint)) {
|
||||||
$xo->element(
|
$xo->element(
|
||||||
'georss:point',
|
'georss:point',
|
||||||
|
|
|
@ -59,6 +59,7 @@ class ActivityVerb
|
||||||
const UNFAVORITE = 'http://ostatus.org/schema/1.0/unfavorite';
|
const UNFAVORITE = 'http://ostatus.org/schema/1.0/unfavorite';
|
||||||
const UNFOLLOW = 'http://ostatus.org/schema/1.0/unfollow';
|
const UNFOLLOW = 'http://ostatus.org/schema/1.0/unfollow';
|
||||||
const LEAVE = 'http://ostatus.org/schema/1.0/leave';
|
const LEAVE = 'http://ostatus.org/schema/1.0/leave';
|
||||||
|
const UNTAG = 'http://ostatus.org/schema/1.0/untag';
|
||||||
|
|
||||||
// For simple profile-update pings; no content to share.
|
// For simple profile-update pings; no content to share.
|
||||||
const UPDATE_PROFILE = 'http://ostatus.org/schema/1.0/update-profile';
|
const UPDATE_PROFILE = 'http://ostatus.org/schema/1.0/update-profile';
|
||||||
|
|
|
@ -458,6 +458,32 @@ class ApiAction extends Action
|
||||||
return $entry;
|
return $entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function twitterListArray($list)
|
||||||
|
{
|
||||||
|
$profile = Profile::staticGet('id', $list->tagger);
|
||||||
|
|
||||||
|
$twitter_list = array();
|
||||||
|
$twitter_list['id'] = $list->id;
|
||||||
|
$twitter_list['name'] = $list->tag;
|
||||||
|
$twitter_list['full_name'] = '@'.$profile->nickname.'/'.$list->tag;;
|
||||||
|
$twitter_list['slug'] = $list->tag;
|
||||||
|
$twitter_list['description'] = $list->description;
|
||||||
|
$twitter_list['subscriber_count'] = $list->subscriberCount();
|
||||||
|
$twitter_list['member_count'] = $list->taggedCount();
|
||||||
|
$twitter_list['uri'] = $list->getUri();
|
||||||
|
|
||||||
|
if (isset($this->auth_user)) {
|
||||||
|
$twitter_list['following'] = $list->hasSubscriber($this->auth_user);
|
||||||
|
} else {
|
||||||
|
$twitter_list['following'] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$twitter_list['mode'] = ($list->private) ? 'private' : 'public';
|
||||||
|
$twitter_list['user'] = $this->twitterUserArray($profile, false);
|
||||||
|
|
||||||
|
return $twitter_list;
|
||||||
|
}
|
||||||
|
|
||||||
function twitterRssEntryArray($notice)
|
function twitterRssEntryArray($notice)
|
||||||
{
|
{
|
||||||
$entry = array();
|
$entry = array();
|
||||||
|
@ -633,6 +659,20 @@ class ApiAction extends Action
|
||||||
$this->elementEnd('group');
|
$this->elementEnd('group');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showTwitterXmlList($twitter_list)
|
||||||
|
{
|
||||||
|
$this->elementStart('list');
|
||||||
|
foreach($twitter_list as $element => $value) {
|
||||||
|
if($element == 'user') {
|
||||||
|
$this->showTwitterXmlUser($value, 'user');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$this->element($element, null, $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->elementEnd('list');
|
||||||
|
}
|
||||||
|
|
||||||
function showTwitterXmlUser($twitter_user, $role='user', $namespaces=false)
|
function showTwitterXmlUser($twitter_user, $role='user', $namespaces=false)
|
||||||
{
|
{
|
||||||
$attrs = array();
|
$attrs = array();
|
||||||
|
@ -1110,6 +1150,65 @@ class ApiAction extends Action
|
||||||
$this->endDocument('xml');
|
$this->endDocument('xml');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showXmlLists($list, $next_cursor=0, $prev_cursor=0)
|
||||||
|
{
|
||||||
|
|
||||||
|
$this->initDocument('xml');
|
||||||
|
$this->elementStart('lists_list');
|
||||||
|
$this->elementStart('lists', array('type' => 'array'));
|
||||||
|
|
||||||
|
if (is_array($list)) {
|
||||||
|
foreach ($list as $l) {
|
||||||
|
$twitter_list = $this->twitterListArray($l);
|
||||||
|
$this->showTwitterXmlList($twitter_list);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while ($list->fetch()) {
|
||||||
|
$twitter_list = $this->twitterListArray($list);
|
||||||
|
$this->showTwitterXmlList($twitter_list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->elementEnd('lists');
|
||||||
|
|
||||||
|
$this->element('next_cursor', null, $next_cursor);
|
||||||
|
$this->element('previous_cursor', null, $prev_cursor);
|
||||||
|
|
||||||
|
$this->elementEnd('lists_list');
|
||||||
|
$this->endDocument('xml');
|
||||||
|
}
|
||||||
|
|
||||||
|
function showJsonLists($list, $next_cursor=0, $prev_cursor=0)
|
||||||
|
{
|
||||||
|
$this->initDocument('json');
|
||||||
|
|
||||||
|
$lists = array();
|
||||||
|
|
||||||
|
if (is_array($list)) {
|
||||||
|
foreach ($list as $l) {
|
||||||
|
$twitter_list = $this->twitterListArray($l);
|
||||||
|
array_push($lists, $twitter_list);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while ($list->fetch()) {
|
||||||
|
$twitter_list = $this->twitterListArray($list);
|
||||||
|
array_push($lists, $twitter_list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$lists_list = array(
|
||||||
|
'lists' => $lists,
|
||||||
|
'next_cursor' => $next_cursor,
|
||||||
|
'next_cursor_str' => strval($next_cursor),
|
||||||
|
'previous_cursor' => $prev_cursor,
|
||||||
|
'previous_cursor_str' => strval($prev_cursor)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->showJsonObjects($lists_list);
|
||||||
|
|
||||||
|
$this->endDocument('json');
|
||||||
|
}
|
||||||
|
|
||||||
function showTwitterXmlUsers($user)
|
function showTwitterXmlUsers($user)
|
||||||
{
|
{
|
||||||
$this->initDocument('xml');
|
$this->initDocument('xml');
|
||||||
|
@ -1171,6 +1270,22 @@ class ApiAction extends Action
|
||||||
$this->endDocument('xml');
|
$this->endDocument('xml');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showSingleJsonList($list)
|
||||||
|
{
|
||||||
|
$this->initDocument('json');
|
||||||
|
$twitter_list = $this->twitterListArray($list);
|
||||||
|
$this->showJsonObjects($twitter_list);
|
||||||
|
$this->endDocument('json');
|
||||||
|
}
|
||||||
|
|
||||||
|
function showSingleXmlList($list)
|
||||||
|
{
|
||||||
|
$this->initDocument('xml');
|
||||||
|
$twitter_list = $this->twitterListArray($list);
|
||||||
|
$this->showTwitterXmlList($twitter_list);
|
||||||
|
$this->endDocument('xml');
|
||||||
|
}
|
||||||
|
|
||||||
function dateTwitter($dt)
|
function dateTwitter($dt)
|
||||||
{
|
{
|
||||||
$dateStr = date('d F Y H:i:s', strtotime($dt));
|
$dateStr = date('d F Y H:i:s', strtotime($dt));
|
||||||
|
@ -1464,6 +1579,40 @@ class ApiAction extends Action
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getTargetList($user=null, $id=null)
|
||||||
|
{
|
||||||
|
$tagger = $this->getTargetUser($user);
|
||||||
|
$list = null;
|
||||||
|
|
||||||
|
if (empty($id)) {
|
||||||
|
$id = $this->arg('id');
|
||||||
|
}
|
||||||
|
|
||||||
|
if($id) {
|
||||||
|
if (is_numeric($id)) {
|
||||||
|
$list = Profile_list::staticGet('id', $id);
|
||||||
|
|
||||||
|
// only if the list with the id belongs to the tagger
|
||||||
|
if(empty($list) || $list->tagger != $tagger->id) {
|
||||||
|
$list = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (empty($list)) {
|
||||||
|
$tag = common_canonical_tag($id);
|
||||||
|
$list = Profile_list::getByTaggerAndTag($tagger->id, $tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($list) && $list->private) {
|
||||||
|
if ($this->auth_user->id == $list->tagger) {
|
||||||
|
return $list;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return $list;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns query argument or default value if not found. Certain
|
* Returns query argument or default value if not found. Certain
|
||||||
* parameters used throughout the API are lightly scrubbed and
|
* parameters used throughout the API are lightly scrubbed and
|
||||||
|
|
207
lib/apilistusers.php
Normal file
207
lib/apilistusers.php
Normal file
|
@ -0,0 +1,207 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Base class for list members and list subscribers 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
|
||||||
|
* @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';
|
||||||
|
|
||||||
|
class ApiListUsersAction extends ApiBareAuthAction
|
||||||
|
{
|
||||||
|
var $list = null;
|
||||||
|
var $user = false;
|
||||||
|
var $create = false;
|
||||||
|
var $delete = false;
|
||||||
|
var $cursor = -1;
|
||||||
|
var $next_cursor = 0;
|
||||||
|
var $prev_cursor = 0;
|
||||||
|
var $users = null;
|
||||||
|
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
// delete list member if method is DELETE or if method is POST and an argument
|
||||||
|
// _method is set to DELETE
|
||||||
|
$this->delete = ($_SERVER['REQUEST_METHOD'] == 'DELETE' ||
|
||||||
|
($this->trimmed('_method') == 'DELETE' &&
|
||||||
|
$_SERVER['REQUEST_METHOD'] == 'POST'));
|
||||||
|
|
||||||
|
// add member if method is POST
|
||||||
|
$this->create = (!$this->delete &&
|
||||||
|
$_SERVER['REQUEST_METHOD'] == 'POST');
|
||||||
|
|
||||||
|
if($this->arg('id')) {
|
||||||
|
$this->user = $this->getTargetUser($this->arg('id'));
|
||||||
|
}
|
||||||
|
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->list = $this->getTargetList($this->arg('user'), $this->arg('list_id'));
|
||||||
|
|
||||||
|
if (empty($this->list)) {
|
||||||
|
$this->clientError(_('Not found'), 404, $this->format);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$this->create && !$this->delete) {
|
||||||
|
$this->getUsers();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function requiresAuth()
|
||||||
|
{
|
||||||
|
return parent::requiresAuth() ||
|
||||||
|
$this->create || $this->delete;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
|
||||||
|
if($this->delete) {
|
||||||
|
return $this->handleDelete();
|
||||||
|
}
|
||||||
|
|
||||||
|
if($this->create) {
|
||||||
|
return $this->handlePost();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch($this->format) {
|
||||||
|
case 'xml':
|
||||||
|
$this->initDocument('xml');
|
||||||
|
$this->elementStart('users_list', array('xmlns:statusnet' =>
|
||||||
|
'http://status.net/schema/api/1/'));
|
||||||
|
$this->elementStart('users', array('type' => 'array'));
|
||||||
|
|
||||||
|
if (is_array($this->users)) {
|
||||||
|
foreach ($this->users as $u) {
|
||||||
|
$twitter_user = $this->twitterUserArray($u, true);
|
||||||
|
$this->showTwitterXmlUser($twitter_user);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while ($this->users->fetch()) {
|
||||||
|
$twitter_user = $this->twitterUserArray($this->users, true);
|
||||||
|
$this->showTwitterXmlUser($twitter_user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->elementEnd('users');
|
||||||
|
$this->element('next_cursor', null, $this->next_cursor);
|
||||||
|
$this->element('previous_cursor', null, $this->prev_cursor);
|
||||||
|
$this->elementEnd('users_list');
|
||||||
|
break;
|
||||||
|
case 'json':
|
||||||
|
$this->initDocument('json');
|
||||||
|
|
||||||
|
$users = array();
|
||||||
|
|
||||||
|
if (is_array($this->users)) {
|
||||||
|
foreach ($this->users as $u) {
|
||||||
|
$twitter_user = $this->twitterUserArray($u, true);
|
||||||
|
array_push($users, $twitter_user);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while ($this->users->fetch()) {
|
||||||
|
$twitter_user = $this->twitterUserArray($this->users, true);
|
||||||
|
array_push($users, $twitter_user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$users_list = array('users' => $users,
|
||||||
|
'next_cursor' => $this->next_cursor,
|
||||||
|
'next_cursor_str' => strval($this->next_cursor),
|
||||||
|
'previous_cursor' => $this->prev_cursor,
|
||||||
|
'previous_cursor_str' => strval($this->prev_cursor));
|
||||||
|
|
||||||
|
$this->showJsonObjects($users_list);
|
||||||
|
|
||||||
|
$this->endDocument('json');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->clientError(
|
||||||
|
_('API method not found.'),
|
||||||
|
404,
|
||||||
|
$this->format
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handlePost()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDelete()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
function getUsers()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
function isReadOnly($args)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function lastModified()
|
||||||
|
{
|
||||||
|
if(!empty($this->list)) {
|
||||||
|
return strtotime($this->list->modified);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An entity tag for this list
|
||||||
|
*
|
||||||
|
* Returns an Etag based on the action name, language, user ID and
|
||||||
|
* timestamps of the first and last list the user has joined
|
||||||
|
*
|
||||||
|
* @return string etag
|
||||||
|
*/
|
||||||
|
|
||||||
|
function etag()
|
||||||
|
{
|
||||||
|
if (!empty($this->list)) {
|
||||||
|
|
||||||
|
return '"' . implode(
|
||||||
|
':',
|
||||||
|
array($this->arg('action'),
|
||||||
|
common_language(),
|
||||||
|
$this->list->id,
|
||||||
|
strtotime($this->list->created),
|
||||||
|
strtotime($this->list->modified))
|
||||||
|
)
|
||||||
|
. '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
105
lib/atomlistnoticefeed.php
Normal file
105
lib/atomlistnoticefeed.php
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Class for building an in-memory Atom feed for a particular list'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 Feed
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2010 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for list notice feeds. May contain a reference to the list.
|
||||||
|
*
|
||||||
|
* @category Feed
|
||||||
|
* @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 AtomListNoticeFeed extends AtomNoticeFeed
|
||||||
|
{
|
||||||
|
private $list;
|
||||||
|
private $tagger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param List $list the list for the feed
|
||||||
|
* @param User $cur the current authenticated user, if any
|
||||||
|
* @param boolean $indent flag to turn indenting on or off
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function __construct($list, $cur = null, $indent = true) {
|
||||||
|
parent::__construct($cur, $indent);
|
||||||
|
$this->list = $list;
|
||||||
|
$this->tagger = Profile::staticGet('id', $list->tagger);
|
||||||
|
|
||||||
|
// TRANS: Title in atom list notice feed. %s is a list name.
|
||||||
|
$title = sprintf(_("Timeline for people tagged #%s by %s"), $list->tag, $this->tagger->nickname);
|
||||||
|
$this->setTitle($title);
|
||||||
|
|
||||||
|
$sitename = common_config('site', 'name');
|
||||||
|
$subtitle = sprintf(
|
||||||
|
// TRANS: Message is used as a subtitle in atom list notice feed.
|
||||||
|
// TRANS: %1$s is a list name, %2$s is a site name.
|
||||||
|
_('Updates from %1$s\'s %2$s people tag on %3$s!'),
|
||||||
|
$this->tagger->nickname,
|
||||||
|
$list->tag,
|
||||||
|
$sitename
|
||||||
|
);
|
||||||
|
$this->setSubtitle($subtitle);
|
||||||
|
|
||||||
|
$avatar = $this->tagger->avatarUrl(AVATAR_PROFILE_SIZE);
|
||||||
|
$this->setLogo($avatar);
|
||||||
|
|
||||||
|
$this->setUpdated('now');
|
||||||
|
|
||||||
|
$self = common_local_url('ApiTimelineList',
|
||||||
|
array('user' => $this->tagger->nickname,
|
||||||
|
'id' => $list->tag,
|
||||||
|
'format' => 'atom'));
|
||||||
|
$this->setId($self);
|
||||||
|
$this->setSelfLink($self);
|
||||||
|
|
||||||
|
// FIXME: Stop using activity:subject?
|
||||||
|
$ao = ActivityObject::fromPeopletag($this->list);
|
||||||
|
|
||||||
|
$this->addAuthorRaw($ao->asString('author').
|
||||||
|
$ao->asString('activity:subject'));
|
||||||
|
|
||||||
|
$this->addLink($this->list->getUri());
|
||||||
|
}
|
||||||
|
|
||||||
|
function getList()
|
||||||
|
{
|
||||||
|
return $this->list;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -766,6 +766,72 @@ class Router
|
||||||
'id' => '[a-zA-Z0-9]+',
|
'id' => '[a-zA-Z0-9]+',
|
||||||
'format' => '(xml|json)'));
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
|
// Lists (people tags)
|
||||||
|
|
||||||
|
$m->connect('api/lists/memberships.:format',
|
||||||
|
array('action' => 'ApiListMemberships',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
|
$m->connect('api/:user/lists/memberships.:format',
|
||||||
|
array('action' => 'ApiListMemberships',
|
||||||
|
'user' => '[a-zA-Z0-9]+',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
|
$m->connect('api/lists/subscriptions.:format',
|
||||||
|
array('action' => 'ApiListSubscriptions',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
|
$m->connect('api/:user/lists/subscriptions.:format',
|
||||||
|
array('action' => 'ApiListSubscriptions',
|
||||||
|
'user' => '[a-zA-Z0-9]+',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
|
$m->connect('api/lists.:format',
|
||||||
|
array('action' => 'ApiLists',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
|
$m->connect('api/:user/lists.:format',
|
||||||
|
array('action' => 'ApiLists',
|
||||||
|
'user' => '[a-zA-Z0-9]+',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
|
$m->connect('api/:user/lists/:id.:format',
|
||||||
|
array('action' => 'ApiList',
|
||||||
|
'user' => '[a-zA-Z0-9]+',
|
||||||
|
'id' => '[a-zA-Z0-9]+',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
|
$m->connect('api/:user/lists/:id/statuses.:format',
|
||||||
|
array('action' => 'ApiTimelineList',
|
||||||
|
'user' => '[a-zA-Z0-9]+',
|
||||||
|
'id' => '[a-zA-Z0-9]+',
|
||||||
|
'format' => '(xml|json|rss|atom)'));
|
||||||
|
|
||||||
|
$m->connect('api/:user/:list_id/members.:format',
|
||||||
|
array('action' => 'ApiListMembers',
|
||||||
|
'user' => '[a-zA-Z0-9]+',
|
||||||
|
'list_id' => '[a-zA-Z0-9]+',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
|
$m->connect('api/:user/:list_id/subscribers.:format',
|
||||||
|
array('action' => 'ApiListSubscribers',
|
||||||
|
'user' => '[a-zA-Z0-9]+',
|
||||||
|
'list_id' => '[a-zA-Z0-9]+',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
|
$m->connect('api/:user/:list_id/members/:id.:format',
|
||||||
|
array('action' => 'ApiListMember',
|
||||||
|
'user' => '[a-zA-Z0-9]+',
|
||||||
|
'list_id' => '[a-zA-Z0-9]+',
|
||||||
|
'id' => '[a-zA-Z0-9]+',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
|
$m->connect('api/:user/:list_id/subscribers/:id.:format',
|
||||||
|
array('action' => 'ApiListSubscriber',
|
||||||
|
'user' => '[a-zA-Z0-9]+',
|
||||||
|
'list_id' => '[a-zA-Z0-9]+',
|
||||||
|
'id' => '[a-zA-Z0-9]+',
|
||||||
|
'format' => '(xml|json)'));
|
||||||
|
|
||||||
// Tags
|
// Tags
|
||||||
$m->connect('api/statusnet/tags/timeline/:tag.:format',
|
$m->connect('api/statusnet/tags/timeline/:tag.:format',
|
||||||
array('action' => 'ApiTimelineTag',
|
array('action' => 'ApiTimelineTag',
|
||||||
|
|
Loading…
Reference in New Issue
Block a user