First cut at some JSON Activity Streams output
This commit is contained in:
parent
ff502bb148
commit
a1b436a8c6
@ -263,6 +263,12 @@ class ApiTimelineFriendsAction extends ApiBareAuthAction
|
|||||||
case 'json':
|
case 'json':
|
||||||
$this->showJsonTimeline($this->notices);
|
$this->showJsonTimeline($this->notices);
|
||||||
break;
|
break;
|
||||||
|
case 'as':
|
||||||
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
|
$doc = new ActivityStreamJSONDocument($this->auth_user);
|
||||||
|
$doc->addItemsFromNotices($this->notices);
|
||||||
|
$this->raw($doc->asString());
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// TRANS: Client error displayed when trying to handle an unknown API method.
|
// TRANS: Client error displayed when trying to handle an unknown API method.
|
||||||
$this->clientError(_('API method not found.'), $code = 404);
|
$this->clientError(_('API method not found.'), $code = 404);
|
||||||
|
@ -1252,18 +1252,19 @@ class Notice extends Memcached_DataObject
|
|||||||
|
|
||||||
function asActivity()
|
function asActivity()
|
||||||
{
|
{
|
||||||
|
common_debug("a");
|
||||||
|
|
||||||
$act = self::cacheGet(Cache::codeKey('notice:as-activity:'.$this->id));
|
$act = self::cacheGet(Cache::codeKey('notice:as-activity:'.$this->id));
|
||||||
|
|
||||||
if (!empty($act)) {
|
if (!empty($act)) {
|
||||||
return $act;
|
return $act;
|
||||||
}
|
}
|
||||||
|
|
||||||
$act = new Activity();
|
$act = new Activity();
|
||||||
|
|
||||||
if (Event::handle('StartNoticeAsActivity', array($this, &$act))) {
|
if (Event::handle('StartNoticeAsActivity', array($this, &$act))) {
|
||||||
|
|
||||||
$profile = $this->getProfile();
|
$profile = $this->getProfile();
|
||||||
|
common_debug('b');
|
||||||
$act->actor = ActivityObject::fromProfile($profile);
|
$act->actor = ActivityObject::fromProfile($profile);
|
||||||
$act->verb = ActivityVerb::POST;
|
$act->verb = ActivityVerb::POST;
|
||||||
$act->objects[] = ActivityObject::fromNotice($this);
|
$act->objects[] = ActivityObject::fromNotice($this);
|
||||||
|
@ -337,6 +337,59 @@ class Activity
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array based on this activity suitable
|
||||||
|
* for encoding as a JSON object
|
||||||
|
*
|
||||||
|
* @return array $activity
|
||||||
|
*/
|
||||||
|
|
||||||
|
function asArray()
|
||||||
|
{
|
||||||
|
$activity = array();
|
||||||
|
|
||||||
|
// actor
|
||||||
|
$activity['actor'] = $this->actor->asArray();
|
||||||
|
|
||||||
|
// body
|
||||||
|
$activity['body'] = $this->content;
|
||||||
|
|
||||||
|
// generator <--- might be useful; might be too much junk
|
||||||
|
|
||||||
|
// icon <-- should we use this?
|
||||||
|
|
||||||
|
// object
|
||||||
|
if ($this->verb == ActivityVerb::POST && count($this->objects) == 1) {
|
||||||
|
$activity['object'] = $this->objects[0]->asArray();
|
||||||
|
} else {
|
||||||
|
$activity['object'] = array();
|
||||||
|
foreach($this->objects as $object) {
|
||||||
|
$activity['object'][] = $object->asArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$activity['postedTime'] = self::iso8601Date($this->time); // Change to exactly be RFC3339?
|
||||||
|
|
||||||
|
// provider <--- again not sure we should use this
|
||||||
|
|
||||||
|
// target
|
||||||
|
if (!empty($this->target)) {
|
||||||
|
$activity['target'] = $this->target->asArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
// title
|
||||||
|
$activity['title'] = $this->title;
|
||||||
|
|
||||||
|
// updatedTime <-- should we use? spec says activity MAY have this
|
||||||
|
|
||||||
|
// verb
|
||||||
|
$activity['verb'] = $this->verb;
|
||||||
|
|
||||||
|
// TODO: extensions (ActivityContext, OStatus stuff, etc.)
|
||||||
|
|
||||||
|
return $activity;
|
||||||
|
}
|
||||||
|
|
||||||
function asString($namespace=false, $author=true, $source=false)
|
function asString($namespace=false, $author=true, $source=false)
|
||||||
{
|
{
|
||||||
$xs = new XMLStringer(true);
|
$xs = new XMLStringer(true);
|
||||||
|
@ -633,4 +633,46 @@ class ActivityObject
|
|||||||
|
|
||||||
return $xs->getString();
|
return $xs->getString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns an array based on this Activity Object suitable for
|
||||||
|
* encoding as JSON.
|
||||||
|
*
|
||||||
|
* @return array $object the activity object array
|
||||||
|
*/
|
||||||
|
|
||||||
|
function asArray()
|
||||||
|
{
|
||||||
|
$object = array();
|
||||||
|
|
||||||
|
// TODO: attachedObjects
|
||||||
|
|
||||||
|
// displayName
|
||||||
|
$object['displayName'] = $this->title;
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: downstreamDuplicates
|
||||||
|
// TODO: embedCode
|
||||||
|
|
||||||
|
// id
|
||||||
|
$object['id'] = $this->id;
|
||||||
|
|
||||||
|
// TODO: image
|
||||||
|
// Need to make MediaLink serialization
|
||||||
|
|
||||||
|
// objectType
|
||||||
|
$object['type'] = $this->type;
|
||||||
|
|
||||||
|
// summary
|
||||||
|
$object['summary'] = $this->summary;
|
||||||
|
|
||||||
|
// TODO: upstreamDuplicates
|
||||||
|
|
||||||
|
// url (XXX: need to put the right thing here...)
|
||||||
|
$object['url'] = $this->id;
|
||||||
|
|
||||||
|
// TODO: extensions (OStatus stuff, etc.)
|
||||||
|
|
||||||
|
return $object;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
112
lib/activitystreamjsondocument.php
Normal file
112
lib/activitystreamjsondocument.php
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Class for serializing Activity Streams in JSON
|
||||||
|
*
|
||||||
|
* 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 2011 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class for generating JSON documents that represent an Activity Streams
|
||||||
|
*
|
||||||
|
* @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 ActivityStreamJSONDocument
|
||||||
|
{
|
||||||
|
/* Top level array representing the document */
|
||||||
|
protected $doc = array();
|
||||||
|
|
||||||
|
/* The current authenticated user */
|
||||||
|
protected $cur = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param User $cur the current authenticated user
|
||||||
|
*/
|
||||||
|
|
||||||
|
function __construct($cur = null)
|
||||||
|
{
|
||||||
|
$this->cur = $cur;
|
||||||
|
|
||||||
|
$this->doc['items'] = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add more than one Item to the document
|
||||||
|
*
|
||||||
|
* @param mixed $notices an array of Notice objects or handle
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
function addItemsFromNotices($notices)
|
||||||
|
{
|
||||||
|
common_debug("addItemsFromNotices");
|
||||||
|
if (is_array($notices)) {
|
||||||
|
foreach ($notices as $notice) {
|
||||||
|
$this->addItemFromNotice($notice);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while ($notices->fetch()) {
|
||||||
|
$this->addItemFromNotice($notices);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a single Notice to the document
|
||||||
|
*
|
||||||
|
* @param Notice $notice a Notice to add
|
||||||
|
*/
|
||||||
|
|
||||||
|
function addItemFromNotice($notice)
|
||||||
|
{
|
||||||
|
$cur = empty($this->cur) ? common_current_user() : $this->cur;
|
||||||
|
|
||||||
|
$act = $notice->asActivity();
|
||||||
|
$act->extra[] = $notice->noticeInfo($cur);
|
||||||
|
|
||||||
|
array_push($this->doc['items'], $act->asArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the entire document as a big string of JSON
|
||||||
|
*
|
||||||
|
* @return string encoded JSON output
|
||||||
|
*/
|
||||||
|
function asString()
|
||||||
|
{
|
||||||
|
return json_encode($this->doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -411,7 +411,7 @@ class Router
|
|||||||
|
|
||||||
$m->connect('api/statuses/friends_timeline.:format',
|
$m->connect('api/statuses/friends_timeline.:format',
|
||||||
array('action' => 'ApiTimelineFriends',
|
array('action' => 'ApiTimelineFriends',
|
||||||
'format' => '(xml|json|rss|atom)'));
|
'format' => '(xml|json|rss|atom|as)'));
|
||||||
|
|
||||||
$m->connect('api/statuses/friends_timeline/:id.:format',
|
$m->connect('api/statuses/friends_timeline/:id.:format',
|
||||||
array('action' => 'ApiTimelineFriends',
|
array('action' => 'ApiTimelineFriends',
|
||||||
|
Loading…
Reference in New Issue
Block a user