Merge branch 'master' into 1.0.x

Conflicts:
	plugins/Blacklist/BlacklistPlugin.php
This commit is contained in:
Evan Prodromou 2012-03-08 06:08:11 -06:00
commit b4da5f3785
31 changed files with 313 additions and 42 deletions

View File

@ -92,8 +92,6 @@ class ApiSearchAtomAction extends ApiPrivateAuthAction
*/
function prepare($args)
{
common_debug("in apisearchatom prepare()");
parent::prepare($args);
$this->query = $this->trimmed('q');

View File

@ -63,8 +63,6 @@ class ApiSearchJSONAction extends ApiPrivateAuthAction
*/
function prepare($args)
{
common_debug("apisearchjson prepare()");
parent::prepare($args);
$this->query = $this->trimmed('q');

View File

@ -159,6 +159,11 @@ class PublicAction extends Action
$this->element('link', array('rel' => 'EditURI',
'type' => 'application/rsd+xml',
'href' => $rsd));
if ($this->page != 1) {
$this->element('link', array('rel' => 'canonical',
'href' => common_local_url('public')));
}
}
/**

View File

@ -288,10 +288,11 @@ class RecoverpasswordAction extends Action
'have been sent to the email address registered to your ' .
'account.');
$this->success = true;
$this->showPage();
} catch (Exception $e) {
$this->success = false;
$this->msg = $e->getMessage();
}
$this->showPage();
}
function resetPassword()

View File

@ -233,4 +233,12 @@ class ShowgroupAction extends GroupAction
$this->raw(common_markup_to_html($m));
$this->elementEnd('div');
}
function extraHead()
{
if ($this->page != 1) {
$this->element('link', array('rel' => 'canonical',
'href' => $this->group->homeUrl()));
}
}
}

View File

@ -212,6 +212,11 @@ class ShowstreamAction extends ProfileAction
$this->element('link', array('rel' => 'EditURI',
'type' => 'application/rsd+xml',
'href' => $rsd));
if ($this->page != 1) {
$this->element('link', array('rel' => 'canonical',
'href' => $this->profile->profileurl));
}
}
function showEmptyListMessage()

View File

@ -29,8 +29,6 @@ class UserrssAction extends Rss10Action
function prepare($args)
{
common_debug("UserrssAction");
parent::prepare($args);
$nickname = $this->trimmed('nickname');
$this->user = User::staticGet('nickname', $nickname);

View File

@ -1086,7 +1086,7 @@ class User extends Managed_DataObject
if (!$user) {
// TRANS: Information on password recovery form if no known username or e-mail address was specified.
throw new ClientError(_('No user with that email address or username.'));
throw new ClientException(_('No user with that email address or username.'));
return;
}

View File

@ -302,7 +302,7 @@ class Action extends HTMLOutputter // lawsuit
$this->script('jquery.form.min.js');
$this->script('jquery-ui.min.js');
$this->script('jquery.cookie.min.js');
$this->inlineScript('if (typeof window.JSON !== "object") { $.getScript("'.common_path('js/json2.min.js').'"); }');
$this->inlineScript('if (typeof window.JSON !== "object") { $.getScript("'.common_path('js/json2.min.js', StatusNet::isHTTPS()).'"); }');
$this->script('jquery.joverlay.min.js');
$this->script('jquery.infieldlabel.min.js');
} else {
@ -310,7 +310,7 @@ class Action extends HTMLOutputter // lawsuit
$this->script('jquery.form.js');
$this->script('jquery-ui.min.js');
$this->script('jquery.cookie.js');
$this->inlineScript('if (typeof window.JSON !== "object") { $.getScript("'.common_path('js/json2.js').'"); }');
$this->inlineScript('if (typeof window.JSON !== "object") { $.getScript("'.common_path('js/json2.js', StatusNet::isHTTPS()).'"); }');
$this->script('jquery.joverlay.js');
$this->script('jquery.infieldlabel.js');
}

View File

@ -389,9 +389,28 @@ class Activity
$activity['geopoint'] = array(
'type' => 'Point',
'coordinates' => array($loc->lat, $loc->lon)
'coordinates' => array($loc->lat, $loc->lon),
'deprecated' => true,
);
$activity['location'] = array(
'objectType' => 'place',
'position' => sprintf("%+02.5F%+03.5F/", $loc->lat, $loc->lon),
'lat' => $loc->lat,
'lon' => $loc->lon
);
$name = $loc->getName();
if ($name) {
$activity['location']['displayName'] = $name;
}
$url = $loc->getURL();
if ($url) {
$activity['location']['url'] = $url;
}
}
$activity['to'] = $this->context->getToArray();
@ -487,15 +506,20 @@ class Activity
/* Purely extensions hereafter */
$tags = array();
// Use an Activity Object for term? Which object? Note?
foreach ($this->categories as $cat) {
$tags[] = $cat->term;
if ($activity['verb'] == 'post') {
$tags = array();
foreach ($this->categories as $cat) {
if (mb_strlen($cat->term) > 0) {
// Couldn't figure out which object type to use, so...
$tags[] = array('objectType' => 'http://activityschema.org/object/hashtag',
'displayName' => $cat->term);
}
}
if (count($tags) > 0) {
$activity['object']['tags'] = $tags;
}
}
$activity['tags'] = $tags;
// XXX: a bit of a hack... Since JSON isn't namespaced we probably
// shouldn't be using 'statusnet:notice_info', but this will work
// for the moment.

View File

@ -692,9 +692,6 @@ class ActivityObject
// id
$object['id'] = $this->id;
//
// XXX: Should we use URL here? or a crazy tag URI?
$object['id'] = $this->id;
if ($this->type == ActivityObject::PERSON
|| $this->type == ActivityObject::GROUP) {
@ -737,14 +734,17 @@ class ActivityObject
// We can probably use the whole schema URL here but probably the
// relative simple name is easier to parse
// @fixme this breaks extension URIs
$object['type'] = substr($this->type, strrpos($this->type, '/') + 1);
// published (probably don't need. Might be useful for repeats.)
$object['objectType'] = substr($this->type, strrpos($this->type, '/') + 1);
// summary
$object['summary'] = $this->summary;
// udpated (probably don't need this)
// summary
$object['content'] = $this->content;
// published (probably don't need. Might be useful for repeats.)
// updated (probably don't need this)
// TODO: upstreamDuplicates

View File

@ -168,7 +168,7 @@ class ActivityStreamJSONDocument extends JSONActivityCollection
$this->doc['generator'] = 'StatusNet ' . STATUSNET_VERSION; // extension
$this->doc['title'] = $this->title;
$this->doc['url'] = $this->url;
$this->doc['count'] = $this->count;
$this->doc['totalItems'] = $this->count;
$this->doc['items'] = $this->items;
$this->doc['links'] = $this->links; // extension
return json_encode(array_filter($this->doc)); // filter out empty elements

View File

@ -66,7 +66,7 @@ $default =
'minify' => true, // true to use the minified versions of JS files; false to use orig files. Can aid during development
),
'db' =>
array('database' => 'YOU HAVE TO SET THIS IN config.php',
array('database' => null, // must be set
'schema_location' => INSTALLDIR . '/classes',
'class_location' => INSTALLDIR . '/classes',
'require_prefix' => 'classes/',

View File

@ -160,6 +160,15 @@ function PEAR_ErrorToPEAR_Exception($err)
common_log(LOG_ERR, "PEAR Error: $msg ($userInfo)");
// HACK: queue handlers get kicked by the long-query killer, and
// keep the same broken connection. We die here to get a new
// process started.
if (php_sapi_name() == 'cli' && preg_match('/nativecode=2006/', $userInfo)) {
common_log(LOG_ERR, "Lost DB connection; dying.");
exit(100);
}
if ($err->getCode()) {
throw new PEAR_Exception($msg, $err, $err->getCode());
} else {

View File

@ -720,4 +720,17 @@ class NoticeListItem extends Widget
Event::handle('EndCloseNoticeListItemElement', array($this));
}
}
/**
* Get the notice in question
*
* For hooks, etc., this may be useful
*
* @return Notice The notice we're showing
*/
function getNotice()
{
return $this->notice;
}
}

View File

@ -159,7 +159,12 @@ class Plugin
}
if (empty($path)) {
$path = common_config('site', 'path') . '/plugins/';
// XXX: extra stat().
if (@file_exists(INSTALLDIR.'/local/plugins/'.$plugin.'/'.$relative)) {
$path = common_config('site', 'path') . '/local/plugins/';
} else {
$path = common_config('site', 'path') . '/plugins/';
}
}
if ($path[strlen($path)-1] != '/') {

View File

@ -127,6 +127,7 @@ abstract class ProfileBlock extends Widget
if (!empty($homepage)) {
$this->out->element('a',
array('href' => $homepage,
'rel' => 'me',
'class' => 'profile_block_homepage'),
$homepage);
}

View File

@ -362,6 +362,7 @@ class StatusNet
if (@file_exists($_config_file)) {
// Ignore 0-byte config files
if (filesize($_config_file) > 0) {
common_log(LOG_INFO, "Including config file: " . $_config_file);
include($_config_file);
self::$have_config = true;
}
@ -383,6 +384,7 @@ class StatusNet
$config['cache']['base'] = $config['memcached']['base'];
}
}
if (array_key_exists('xmpp', $config)) {
if ($config['xmpp']['enabled']) {
addPlugin('xmpp', array(
@ -398,6 +400,12 @@ class StatusNet
));
}
}
// Check for database server; must exist!
if (empty($config['db']['database'])) {
throw new ServerException("No database server for this site.");
}
}
/**

View File

@ -80,6 +80,19 @@ class Widget
{
}
/**
* Get HTMLOutputter
*
* Return the HTMLOutputter for the widget.
*
* @return HTMLOutputter the output helper
*/
function getOut()
{
return $this->out;
}
/**
* Delegate output methods to the outputter attribute.
*

View File

@ -505,14 +505,16 @@ class BlacklistPlugin extends Plugin
}
}
$nickname = strtolower($actor->poco->preferredUsername);
if (!empty($actor->poco)) {
$nickname = strtolower($actor->poco->preferredUsername);
if (!empty($nickname)) {
if (!$this->_checkNickname($nickname)) {
// TRANS: Exception thrown trying to post a notice while having a blocked nickname. %s is the blocked nickname.
$msg = sprintf(_m("Notices from nickname \"%s\" are disallowed."),
$nickname);
throw new ClientException($msg);
if (!empty($nickname)) {
if (!$this->_checkNickname($nickname)) {
// TRANS: Exception thrown trying to post a notice while having a blocked nickname. %s is the blocked nickname.
$msg = sprintf(_m("Notices from nickname \"%s\" disallowed."),
$nickname);
throw new ClientException($msg);
}
}
}

View File

@ -572,4 +572,20 @@ class BookmarkPlugin extends MicroAppPlugin
$notice->update($original);
}
}
public function activityObjectOutputJson(ActivityObject $obj, array &$out)
{
assert($obj->type == ActivityObject::BOOKMARK);
$bm = Bookmark::staticGet('uri', $obj->id);
if (empty($bm)) {
throw new ServerException("Unknown bookmark: " . $obj->id);
}
$out['displayName'] = $bm->title;
$out['targetUrl'] = $bm->url;
return true;
}
}

View File

@ -176,7 +176,8 @@ class Facebookclient
// If it's not a reply, or if the user WANTS to send @-replies,
// then, yeah, it can go to Facebook.
if (!preg_match('/@[a-zA-Z0-9_]{1,15}\b/u', $this->notice->content) ||
if (empty($this->notice->reply_to) ||
($this->flink->noticesync & FOREIGN_NOTICE_SEND_REPLY)) {
return true;
}

View File

@ -0,0 +1,41 @@
#!/usr/bin/env php
<?php
/*
* StatusNet - a distributed open-source microblogging tool
* Copyright (C) 2010, StatusNet, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
define('INSTALLDIR', realpath(dirname(__FILE__) . '/../../..'));
$helptext = <<<END_OF_HELP
gcfeeds.php [options]
Clean up feeds that no longer have subscribers.
END_OF_HELP;
require_once INSTALLDIR.'/scripts/commandline.inc';
$feedsub = new FeedSub();
while ($feedsub->fetch()) {
print $feedsub->uri . "(" . $feedsub->sub_state . ")";
$result = $feedsub->garbageCollect();
if ($result) {
print " INACTIVE\n";
} else {
print " ACTIVE\n";
}
}

View File

@ -223,6 +223,7 @@ class RegisterThrottlePlugin extends Plugin
private function _getIpAddress()
{
$keys = array('HTTP_X_FORWARDED_FOR',
'HTTP_X_CLIENT',
'CLIENT-IP',
'REMOTE_ADDR');

View File

@ -65,6 +65,9 @@ class SphinxSearch extends SearchEngine
function query($q)
{
$result = $this->sphinx->query($q, $this->remote_table());
if ($result === false) {
throw new ServerException($this->sphinx->getLastError());
}
if (!isset($result['matches'])) return false;
$id_set = join(', ', array_keys($result['matches']));
$this->target->whereAdd("id in ($id_set)");

View File

@ -157,6 +157,10 @@ class SubMirrorPlugin extends Plugin
*/
function onOstatus_profileSubscriberCount($oprofile, &$count)
{
if (empty($oprofile) || !($oprofile instanceof Ostatus_profile)) {
return true;
}
if ($oprofile->profile_id) {
$mirror = new SubMirror();
$mirror->subscribed = $oprofile->profile_id;
@ -166,6 +170,7 @@ class SubMirrorPlugin extends Plugin
}
}
}
return true;
}

View File

@ -157,7 +157,7 @@ class SubMirror extends Memcached_DataObject
{
$profile = Profile::staticGet('id', $this->subscriber);
if (!$profile) {
common_log(LOG_ERROR, "SubMirror plugin skipping auto-repeat of notice $notice->id for missing user $profile->id");
common_log(LOG_ERR, "SubMirror plugin skipping auto-repeat of notice $notice->id for missing user $profile->id");
return false;
}

View File

@ -339,7 +339,7 @@ class TwitterBridgePlugin extends Plugin
$versions[] = array(
'name' => 'TwitterBridge',
'version' => self::VERSION,
'author' => 'Zach Copley, Julien C',
'author' => 'Zach Copley, Julien C, Jean Baptiste Favre',
'homepage' => 'http://status.net/wiki/Plugin:TwitterBridge',
// TRANS: Plugin description.
'rawdescription' => _m('The Twitter "bridge" plugin allows integration ' .

View File

@ -116,13 +116,13 @@ function is_twitter_bound($notice, $flink) {
}
// Check to see if notice should go to Twitter
if (!empty($flink) && ($flink->noticesync & FOREIGN_NOTICE_SEND == FOREIGN_NOTICE_SEND)) {
if (!empty($flink) && (($flink->noticesync & FOREIGN_NOTICE_SEND) == FOREIGN_NOTICE_SEND)) {
// If it's not a Twitter-style reply, or if the user WANTS to send replies,
// or if it's in reply to a twitter notice
if (!preg_match('/^@[a-zA-Z0-9_]{1,15}\b/u', $notice->content) ||
($flink->noticesync & FOREIGN_NOTICE_SEND_REPLY == FOREIGN_NOTICE_SEND_REPLY) ||
is_twitter_notice($notice->reply_to)) {
if ( (($flink->noticesync & FOREIGN_NOTICE_SEND_REPLY) == FOREIGN_NOTICE_SEND_REPLY) ||
(is_twitter_notice($notice->reply_to) || is_twitter_notice($notice->repeat_of)) ||
(empty($notice->reply_to) && !preg_match('/^@[a-zA-Z0-9_]{1,15}\b/u', $notice->content)) ){
return true;
}
}

58
scripts/joingroup.php Normal file
View File

@ -0,0 +1,58 @@
<?php
/*
* StatusNet - the distributed open-source microblogging tool
* Copyright (C) 2012 StatusNet, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
$shortoptions = 'i:n:g:G:';
$longoptions = array('id=', 'nickname=', 'group=', 'group-id=');
$helptext = <<<END_OF_HELP
addusertogroup.php [options]
Adds a local user to a local group.
-i --id ID of user to add
-n --nickname nickname of the user to add
-g --group nickname or alias of group
-G --group-id ID of group
END_OF_HELP;
require_once INSTALLDIR.'/scripts/commandline.inc';
try {
$user = getUser();
$lgroup = null;
if (have_option('G', 'group-id')) {
$gid = get_option_value('G', 'group-id');
$lgroup = Local_group::staticGet('group_id', $gid);
} else if (have_option('g', 'group')) {
$gnick = get_option_value('g', 'group');
$lgroup = Local_group::staticGet('nickname', $gnick);
}
if (empty($lgroup)) {
throw new Exception("No such local group: $gnick");
}
$group = User_group::staticGet('id', $lgroup->group_id);
$user->joinGroup($group);
print "OK\n";
} catch (Exception $e) {
print $e->getMessage()."\n";
exit(1);
}

58
scripts/leavegroup.php Normal file
View File

@ -0,0 +1,58 @@
<?php
/*
* StatusNet - the distributed open-source microblogging tool
* Copyright (C) 2012 StatusNet, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
$shortoptions = 'i:n:g:G:';
$longoptions = array('id=', 'nickname=', 'group=', 'group-id=');
$helptext = <<<END_OF_HELP
leavegroup.php [options]
Removes a local user from a local group.
-i --id ID of user to remove
-n --nickname nickname of the user to remove
-g --group nickname or alias of group
-G --group-id ID of group
END_OF_HELP;
require_once INSTALLDIR.'/scripts/commandline.inc';
try {
$user = getUser();
$lgroup = null;
if (have_option('G', 'group-id')) {
$gid = get_option_value('G', 'group-id');
$lgroup = Local_group::staticGet('group_id', $gid);
} else if (have_option('g', 'group')) {
$gnick = get_option_value('g', 'group');
$lgroup = Local_group::staticGet('nickname', $gnick);
}
if (empty($lgroup)) {
throw new Exception("No such local group: $gnick");
}
$group = User_group::staticGet('id', $lgroup->group_id);
$user->leaveGroup($group);
print "OK\n";
} catch (Exception $e) {
print $e->getMessage()."\n";
exit(1);
}