Merge branch 'master' into testing

This commit is contained in:
Brion Vibber 2010-06-26 10:16:27 -04:00
commit d9e56e15cc
16 changed files with 147 additions and 51 deletions

View File

@ -75,7 +75,7 @@ class ApiAccountVerifyCredentialsAction extends ApiAuthAction
if ($this->format == 'xml') { if ($this->format == 'xml') {
$this->initDocument('xml'); $this->initDocument('xml');
$this->showTwitterXmlUser($twitter_user); $this->showTwitterXmlUser($twitter_user, 'user', true);
$this->endDocument('xml'); $this->endDocument('xml');
} elseif ($this->format == 'json') { } elseif ($this->format == 'json') {
$this->initDocument('json'); $this->initDocument('json');

View File

@ -22,7 +22,7 @@
* @category Search * @category Search
* @package StatusNet * @package StatusNet
* @author Zach Copley <zach@status.net> * @author Zach Copley <zach@status.net>
* @copyright 2008-2009 StatusNet, Inc. * @copyright 2008-2010 StatusNet, Inc.
* @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/
*/ */
@ -31,6 +31,8 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
exit(1); exit(1);
} }
require_once INSTALLDIR.'/lib/apiprivateauth.php';
/** /**
* Action for outputting search results in Twitter compatible Atom * Action for outputting search results in Twitter compatible Atom
* format. * format.
@ -44,10 +46,10 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
* @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 ApiAction * @see ApiPrivateAuthAction
*/ */
class TwitapisearchatomAction extends ApiAction class ApiSearchAtomAction extends ApiPrivateAuthAction
{ {
var $cnt; var $cnt;
@ -96,8 +98,11 @@ class TwitapisearchatomAction extends ApiAction
function prepare($args) function prepare($args)
{ {
common_debug("in apisearchatom prepare()");
parent::prepare($args); parent::prepare($args);
$this->query = $this->trimmed('q'); $this->query = $this->trimmed('q');
$this->lang = $this->trimmed('lang'); $this->lang = $this->trimmed('lang');
$this->rpp = $this->trimmed('rpp'); $this->rpp = $this->trimmed('rpp');
@ -138,6 +143,7 @@ class TwitapisearchatomAction extends ApiAction
function handle($args) function handle($args)
{ {
parent::handle($args); parent::handle($args);
common_debug("In apisearchatom handle()");
$this->showAtom(); $this->showAtom();
} }

View File

@ -22,7 +22,7 @@
* @category Search * @category Search
* @package StatusNet * @package StatusNet
* @author Zach Copley <zach@status.net> * @author Zach Copley <zach@status.net>
* @copyright 2008-2009 StatusNet, Inc. * @copyright 2008-2010 StatusNet, Inc.
* @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/
*/ */
@ -31,6 +31,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
exit(1); exit(1);
} }
require_once INSTALLDIR.'/lib/apiprivateauth.php';
require_once INSTALLDIR.'/lib/jsonsearchresultslist.php'; require_once INSTALLDIR.'/lib/jsonsearchresultslist.php';
/** /**
@ -44,7 +45,7 @@ require_once INSTALLDIR.'/lib/jsonsearchresultslist.php';
* @see ApiAction * @see ApiAction
*/ */
class TwitapisearchjsonAction extends ApiAction class ApiSearchJSONAction extends ApiPrivateAuthAction
{ {
var $query; var $query;
var $lang; var $lang;
@ -64,6 +65,8 @@ class TwitapisearchjsonAction extends ApiAction
function prepare($args) function prepare($args)
{ {
common_debug("apisearchjson prepare()");
parent::prepare($args); parent::prepare($args);
$this->query = $this->trimmed('q'); $this->query = $this->trimmed('q');

View File

@ -206,7 +206,8 @@ class ApiSubscriptionsAction extends ApiBareAuthAction
{ {
switch ($this->format) { switch ($this->format) {
case 'xml': case 'xml':
$this->elementStart('users', array('type' => 'array')); $this->elementStart('users', array('type' => 'array',
'xmlns:statusnet' => 'http://status.net/schema/api/1/'));
foreach ($this->profiles as $profile) { foreach ($this->profiles as $profile) {
$this->showProfile( $this->showProfile(
$profile, $profile,

View File

@ -22,7 +22,7 @@
* @category Search * @category Search
* @package StatusNet * @package StatusNet
* @author Zach Copley <zach@status.net> * @author Zach Copley <zach@status.net>
* @copyright 2008-2009 StatusNet, Inc. * @copyright 2008-2010 StatusNet, Inc.
* @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/
*/ */
@ -31,6 +31,8 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
exit(1); exit(1);
} }
require_once INSTALLDIR.'/lib/apiprivateauth.php';
/** /**
* Returns the top ten queries that are currently trending * Returns the top ten queries that are currently trending
* *
@ -43,7 +45,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
* @see ApiAction * @see ApiAction
*/ */
class TwitapitrendsAction extends ApiAction class ApiTrendsAction extends ApiPrivateAuthAction
{ {
var $callback; var $callback;
@ -82,7 +84,7 @@ class TwitapitrendsAction extends ApiAction
*/ */
function showTrends() function showTrends()
{ {
$this->serverError(_('API method under construction.'), $code = 501); $this->serverError(_('API method under construction.'), 501);
} }
} }

View File

@ -430,14 +430,6 @@ class ShowgroupAction extends GroupDesignAction
function showStatistics() function showStatistics()
{ {
// XXX: WORM cache this
$members = $this->group->getMembers();
$members_count = 0;
/** $member->count() doesn't work. */
while ($members->fetch()) {
$members_count++;
}
$this->elementStart('div', array('id' => 'entity_statistics', $this->elementStart('div', array('id' => 'entity_statistics',
'class' => 'section')); 'class' => 'section'));
@ -451,7 +443,7 @@ class ShowgroupAction extends GroupDesignAction
$this->elementStart('dl', 'entity_members'); $this->elementStart('dl', 'entity_members');
$this->element('dt', null, _('Members')); $this->element('dt', null, _('Members'));
$this->element('dd', null, (is_int($members_count)) ? $members_count : '0'); $this->element('dd', null, $this->group->getMemberCount());
$this->elementEnd('dl'); $this->elementEnd('dl');
$this->elementEnd('div'); $this->elementEnd('div');

View File

@ -1190,7 +1190,7 @@ class Notice extends Memcached_DataObject
'xmlns:media' => 'http://purl.org/syndication/atommedia', 'xmlns:media' => 'http://purl.org/syndication/atommedia',
'xmlns:poco' => 'http://portablecontacts.net/spec/1.0', 'xmlns:poco' => 'http://portablecontacts.net/spec/1.0',
'xmlns:ostatus' => 'http://ostatus.org/schema/1.0', 'xmlns:ostatus' => 'http://ostatus.org/schema/1.0',
'xmlns:statusnet' => 'http://status.net/ont/'); 'xmlns:statusnet' => 'http://status.net/schema/api/1/');
} else { } else {
$attrs = array(); $attrs = array();
} }
@ -1225,7 +1225,7 @@ class Notice extends Memcached_DataObject
$xs->element('title', null, common_xml_safe_str($this->content)); $xs->element('title', null, common_xml_safe_str($this->content));
if ($author) { if ($author) {
$xs->raw($profile->asAtomAuthor()); $xs->raw($profile->asAtomAuthor($cur));
$xs->raw($profile->asActivityActor()); $xs->raw($profile->asActivityActor());
} }
@ -1238,9 +1238,25 @@ class Notice extends Memcached_DataObject
$xs->element('published', null, common_date_w3dtf($this->created)); $xs->element('published', null, common_date_w3dtf($this->created));
$xs->element('updated', null, common_date_w3dtf($this->created)); $xs->element('updated', null, common_date_w3dtf($this->created));
$source = null;
$ns = $this->getSource();
if ($ns) {
if (!empty($ns->name) && !empty($ns->url)) {
$source = '<a href="'
. htmlspecialchars($ns->url)
. '" rel="nofollow">'
. htmlspecialchars($ns->name)
. '</a>';
} else {
$source = $ns->code;
}
}
$noticeInfoAttr = array( $noticeInfoAttr = array(
'local_id' => $this->id, // local notice ID (useful to clients for ordering) 'local_id' => $this->id, // local notice ID (useful to clients for ordering)
'source' => $this->source, // the client name (source attribution) 'source' => $source, // the client name (source attribution)
); );
$ns = $this->getSource(); $ns = $this->getSource();
@ -1252,8 +1268,8 @@ class Notice extends Memcached_DataObject
if (!empty($cur)) { if (!empty($cur)) {
$noticeInfoAttr['favorite'] = ($cur->hasFave($this)) ? "true" : "false"; $noticeInfoAttr['favorite'] = ($cur->hasFave($this)) ? "true" : "false";
$profile = $cur->getProfile(); $profile = $cur->getProfile();
$noticeInfoAttr['repeated'] = ($profile->hasRepeated($this->id)) ? "true" : "false"; $noticeInfoAttr['repeated'] = ($profile->hasRepeated($this->id)) ? "true" : "false";
} }
if (!empty($this->repeat_of)) { if (!empty($this->repeat_of)) {

View File

@ -849,15 +849,23 @@ class Profile extends Memcached_DataObject
* *
* Assumes that Atom has been previously set up as the base namespace. * Assumes that Atom has been previously set up as the base namespace.
* *
* @param Profile $cur the current authenticated user
*
* @return string * @return string
*/ */
function asAtomAuthor() function asAtomAuthor($cur = null)
{ {
$xs = new XMLStringer(true); $xs = new XMLStringer(true);
$xs->elementStart('author'); $xs->elementStart('author');
$xs->element('name', null, $this->nickname); $xs->element('name', null, $this->nickname);
$xs->element('uri', null, $this->getUri()); $xs->element('uri', null, $this->getUri());
if ($cur != null) {
$attrs = Array();
$attrs['following'] = $cur->isSubscribed($this) ? 'true' : 'false';
$attrs['blocking'] = $cur->hasBlocked($this) ? 'true' : 'false';
$xs->element('statusnet:profile_info', $attrs, null);
}
$xs->elementEnd('author'); $xs->elementEnd('author');
return $xs->getString(); return $xs->getString();

View File

@ -154,6 +154,21 @@ class User_group extends Memcached_DataObject
return $members; return $members;
} }
function getMemberCount()
{
// XXX: WORM cache this
$members = $this->getMembers();
$member_count = 0;
/** $member->count() doesn't work. */
while ($members->fetch()) {
$member_count++;
}
return $member_count;
}
function getAdmins($offset=0, $limit=null) function getAdmins($offset=0, $limit=null)
{ {
$qry = $qry =

View File

@ -208,11 +208,13 @@ class ApiAction extends Action
// Is the requesting user following this user? // Is the requesting user following this user?
$twitter_user['following'] = false; $twitter_user['following'] = false;
$twitter_user['statusnet:blocking'] = false;
$twitter_user['notifications'] = false; $twitter_user['notifications'] = false;
if (isset($this->auth_user)) { if (isset($this->auth_user)) {
$twitter_user['following'] = $this->auth_user->isSubscribed($profile); $twitter_user['following'] = $this->auth_user->isSubscribed($profile);
$twitter_user['statusnet:blocking'] = $this->auth_user->hasBlocked($profile);
// Notifications on? // Notifications on?
$sub = Subscription::pkeyGet(array('subscriber' => $sub = Subscription::pkeyGet(array('subscriber' =>
@ -346,20 +348,32 @@ class ApiAction extends Action
function twitterGroupArray($group) function twitterGroupArray($group)
{ {
$twitter_group=array(); $twitter_group = array();
$twitter_group['id']=$group->id;
$twitter_group['url']=$group->permalink(); $twitter_group['id'] = $group->id;
$twitter_group['nickname']=$group->nickname; $twitter_group['url'] = $group->permalink();
$twitter_group['fullname']=$group->fullname; $twitter_group['nickname'] = $group->nickname;
$twitter_group['original_logo']=$group->original_logo; $twitter_group['fullname'] = $group->fullname;
$twitter_group['homepage_logo']=$group->homepage_logo;
$twitter_group['stream_logo']=$group->stream_logo; if (isset($this->auth_user)) {
$twitter_group['mini_logo']=$group->mini_logo; $twitter_group['member'] = $this->auth_user->isMember($group);
$twitter_group['homepage']=$group->homepage; $twitter_group['blocked'] = Group_block::isBlocked(
$twitter_group['description']=$group->description; $group,
$twitter_group['location']=$group->location; $this->auth_user->getProfile()
$twitter_group['created']=$this->dateTwitter($group->created); );
$twitter_group['modified']=$this->dateTwitter($group->modified); }
$twitter_group['member_count'] = $group->getMemberCount();
$twitter_group['original_logo'] = $group->original_logo;
$twitter_group['homepage_logo'] = $group->homepage_logo;
$twitter_group['stream_logo'] = $group->stream_logo;
$twitter_group['mini_logo'] = $group->mini_logo;
$twitter_group['homepage'] = $group->homepage;
$twitter_group['description'] = $group->description;
$twitter_group['location'] = $group->location;
$twitter_group['created'] = $this->dateTwitter($group->created);
$twitter_group['modified'] = $this->dateTwitter($group->modified);
return $twitter_group; return $twitter_group;
} }

View File

@ -93,4 +93,23 @@ class AtomGroupNoticeFeed extends AtomNoticeFeed
return $this->group; return $this->group;
} }
function initFeed()
{
parent::initFeed();
$attrs = array();
if (!empty($this->cur)) {
$attrs['member'] = $this->cur->isMember($this->group)
? 'true' : 'false';
$attrs['blocked'] = Group_block::isBlocked(
$this->group,
$this->cur->getProfile()
) ? 'true' : 'false';
}
$attrs['member_count'] = $this->group->getMemberCount();
$this->element('statusnet:group_info', $attrs, null);
}
} }

View File

@ -95,7 +95,7 @@ class AtomNoticeFeed extends Atom10Feed
$this->addNamespace( $this->addNamespace(
'statusnet', 'statusnet',
'http://status.net/ont/' 'http://status.net/schema/api/1/'
); );
} }

View File

@ -76,8 +76,8 @@ class AvatarLink
$alink = new AvatarLink(); $alink = new AvatarLink();
$alink->url = $filename; $alink->url = $filename;
$alink->height = $size; $alink->height = $size;
$alink->width = $size;
if (!empty($filename)) { if (!empty($filename)) {
$alink->width = $size;
$alink->type = self::mediatype($filename); $alink->type = self::mediatype($filename);
} else { } else {
$alink->url = User_group::defaultLogo($size); $alink->url = User_group::defaultLogo($size);

View File

@ -667,9 +667,9 @@ class Router
); );
// search // search
$m->connect('api/search.atom', array('action' => 'twitapisearchatom')); $m->connect('api/search.atom', array('action' => 'ApiSearchAtom'));
$m->connect('api/search.json', array('action' => 'twitapisearchjson')); $m->connect('api/search.json', array('action' => 'ApiSearchJSON'));
$m->connect('api/trends.json', array('action' => 'twitapitrends')); $m->connect('api/trends.json', array('action' => 'ApiTrends'));
$m->connect('api/oauth/request_token', $m->connect('api/oauth/request_token',
array('action' => 'apioauthrequesttoken')); array('action' => 'apioauthrequesttoken'));

View File

@ -2620,7 +2620,7 @@ msgstr "Profil-Einstellungen ansehen"
#: actions/othersettings.php:123 #: actions/othersettings.php:123
msgid "Show or hide profile designs." msgid "Show or hide profile designs."
msgstr "Prifil-Designs anzeigen oder verstecken." msgstr "Profil-Designs anzeigen oder verstecken."
#: actions/othersettings.php:153 #: actions/othersettings.php:153
msgid "URL shortening service is too long (max 50 chars)." msgid "URL shortening service is too long (max 50 chars)."

View File

@ -62,12 +62,32 @@ class RecaptchaPlugin extends Plugin
{ {
$action->elementStart('li'); $action->elementStart('li');
$action->raw('<label for="recaptcha">Captcha</label>'); $action->raw('<label for="recaptcha">Captcha</label>');
if($this->checkssl() === true) {
$action->raw(recaptcha_get_html($this->public_key), null, true); // AJAX API will fill this div out.
} else { // We're calling that instead of the regular one so we stay compatible
$action->raw(recaptcha_get_html($this->public_key)); // with application/xml+xhtml output as for mobile.
} $action->element('div', array('id' => 'recaptcha'));
$action->elementEnd('li'); $action->elementEnd('li');
$action->recaptchaPluginNeedsOutput = true;
return true;
}
function onEndShowScripts($action)
{
if (isset($action->recaptchaPluginNeedsOutput) && $action->recaptchaPluginNeedsOutput) {
// Load the AJAX API
if ($this->checkssl()) {
$url = "https://api-secure.recaptcha.net/js/recaptcha_ajax.js";
} else {
$url = "http://api.recaptcha.net/js/recaptcha_ajax.js";
}
$action->script($url);
// And when we're ready, fill out the captcha!
$key = json_encode($this->public_key);
$action->inlinescript("\$(function(){Recaptcha.create($key, 'recaptcha');});");
}
return true; return true;
} }