merge 0.9.x into 1.0.x

This commit is contained in:
Evan Prodromou 2011-05-04 14:59:39 -07:00
commit c97048d01b
13 changed files with 318 additions and 68 deletions

96
README
View File

@ -2,8 +2,8 @@
README README
------ ------
StatusNet 0.9.6 "Man on the Moon" StatusNet 0.9.7 "World Leader Pretend"
29 October 2010 17 March 2011
This is the README file for StatusNet, the Open Source microblogging This is the README file for StatusNet, the Open Source microblogging
platform. It includes installation instructions, descriptions of platform. It includes installation instructions, descriptions of
@ -96,43 +96,47 @@ for additional terms.
New this version New this version
================ ================
This is a security, bug and feature release since version 0.9.5 released on This is a security, bug and feature release since version 0.9.6 released on
10 September 2010. 23 October 2010.
For best compatibility with client software and site federation, and a lot of For best compatibility with client software and site federation, and a
bug fixes, it is highly recommended that all public sites upgrade to the new lot of bug fixes, it is highly recommended that all public sites
version. upgrade to the new version. Upgrades require new database indexes for
best performance; see Upgrade below.
Notable changes this version: Notable changes this version:
- Site moderators can now delete groups. - GroupPrivateMessage plugin lets users send private messages
- New themes: clean, shiny, mnml, victorian to a group. (Similar to "private groups" on Yammer.)
- New YammerImport plugin allows site admins to import non-private profiles and - Support for Twitter streaming API in Twitter bridge plugin
message from an authenticated Yammer site. - Support for a new Activity Streams-based API using AtomPub, allowing
- New experimental plugins: AnonFavorites, SlicedFavorites, GroupFavorited, richer API data. See http://status.net/wiki/AtomPub for details.
ForceGroup, ShareNotice - Unified Facebook plugin, replacing previous Facebook application
- OAuth upgraded to 1.0a and Facebook Connect plugin.
- Localization updates now include plugins, thanks to translatewiki.net! - A plugin to send out a daily summary email to network users.
- SSL link generation should be more consistent; alternate SSL URLs can be - In-line thumbnails of some attachments (video, images) and oEmbed objects.
set in the admin UI for more parts of the system. - Local copies of remote profiles to let moderators manage OStatus users.
- Experimental backupuser.php, restoreuser.php command-line scripts to - Upgrade upstream JS, minify everything.
dump/restore a user's complete activity stream. Can be used to transfer - Allow pushing plugin JS, CSS, and static files to a CDN.
accounts manually between sites, or to save a backup before deleting. - Configurable nickname rules.
- Unicode fixes for OStatus notices - Better support for bit.ly URL shortener.
- Header metadata on notice pages to aid in manual reposting on Facebook - InProcessCache plugin for additional caching on top of memcached.
- Lots of little fixes... - Support for Activity Streams JSON feeds on many streams.
- User-initiated backup and restore of account data in Activity Streams
format.
- Bookmark plugin for making del.icio.us-like social bookmarking sites,
including del.icio.us backup file import. Supports OStatus.
- SQLProfile plugin to tune SQL queries.
- Better sorting on timelines to support restored or imported data.
- Hundreds of translations from http://translatewiki.net/
- Hundreds of performance tunings, bug fixes, and UI improvements.
- Remove deprecated data from Activity Streams Atom output, to the
extent possible.
- NewMenu plugin for new layout of menu items.
- Experimental support for moving an account from one server to
another, using new AtomPub API.
Changes from 0.9.6 release candidate 1: A full changelog is available at http://status.net/wiki/StatusNet_0.9.7.
- fix for broken group pages when logged out
- fix for stuck ping queue entries when bad profile
- fix for bogus single-user nickname config entry error
- i18n updates
- nofollow updates
- SSL-only mode secure cookie fix
- experimental ApiLogger plugin for usage data gathering
- experimental follow-everyone plugin
A full changelog is available at http://status.net/wiki/StatusNet_0.9.6.
Prerequisites Prerequisites
============= =============
@ -243,9 +247,9 @@ especially if you've previously installed PHP/MySQL packages.
1. Unpack the tarball you downloaded on your Web server. Usually a 1. Unpack the tarball you downloaded on your Web server. Usually a
command like this will work: command like this will work:
tar zxf statusnet-0.9.6.tar.gz tar zxf statusnet-0.9.7.tar.gz
...which will make a statusnet-0.9.6 subdirectory in your current ...which will make a statusnet-0.9.7 subdirectory in your current
directory. (If you don't have shell access on your Web server, you directory. (If you don't have shell access on your Web server, you
may have to unpack the tarball on your local computer and FTP the may have to unpack the tarball on your local computer and FTP the
files to the server.) files to the server.)
@ -253,7 +257,7 @@ especially if you've previously installed PHP/MySQL packages.
2. Move the tarball to a directory of your choosing in your Web root 2. Move the tarball to a directory of your choosing in your Web root
directory. Usually something like this will work: directory. Usually something like this will work:
mv statusnet-0.9.6 /var/www/statusnet mv statusnet-0.9.7 /var/www/statusnet
This will make your StatusNet instance available in the statusnet path of This will make your StatusNet instance available in the statusnet path of
your server, like "http://example.net/statusnet". "microblog" or your server, like "http://example.net/statusnet". "microblog" or
@ -668,7 +672,7 @@ with this situation.
If you've been using StatusNet 0.7, 0.6, 0.5 or lower, or if you've If you've been using StatusNet 0.7, 0.6, 0.5 or lower, or if you've
been tracking the "git" version of the software, you will probably been tracking the "git" version of the software, you will probably
want to upgrade and keep your existing data. There is no automated want to upgrade and keep your existing data. There is no automated
upgrade procedure in StatusNet 0.9.6. Try these step-by-step upgrade procedure in StatusNet 0.9.7. Try these step-by-step
instructions; read to the end first before trying them. instructions; read to the end first before trying them.
0. Download StatusNet and set up all the prerequisites as if you were 0. Download StatusNet and set up all the prerequisites as if you were
@ -689,25 +693,30 @@ instructions; read to the end first before trying them.
5. Once all writing processes to your site are turned off, make a 5. Once all writing processes to your site are turned off, make a
final backup of the Web directory and database. final backup of the Web directory and database.
6. Move your StatusNet directory to a backup spot, like "statusnet.bak". 6. Move your StatusNet directory to a backup spot, like "statusnet.bak".
7. Unpack your StatusNet 0.9.6 tarball and move it to "statusnet" or 7. Unpack your StatusNet 0.9.7 tarball and move it to "statusnet" or
wherever your code used to be. wherever your code used to be.
8. Copy the config.php file and the contents of the avatar/, background/, 8. Copy the config.php file and the contents of the avatar/, background/,
file/, and local/ subdirectories from your old directory to your new file/, and local/ subdirectories from your old directory to your new
directory. directory.
9. Copy htaccess.sample to .htaccess in the new directory. Change the 9. Copy htaccess.sample to .htaccess in the new directory. Change the
RewriteBase to use the correct path. RewriteBase to use the correct path.
10. Rebuild the database. (You can safely skip this step and go to #12 10. Rebuild the database.
if you're upgrading from another 0.9.x version).
NOTE: this step is destructive and cannot be NOTE: this step is destructive and cannot be
reversed. YOU CAN EASILY DESTROY YOUR SITE WITH THIS STEP. Don't reversed. YOU CAN EASILY DESTROY YOUR SITE WITH THIS STEP. Don't
do it without a known-good backup! do it without a known-good backup!
If your database is at version 0.8.0 or above, you can run a If your database is at version 0.8.0 or higher in the 0.8.x line, you can run a
special upgrade script: special upgrade script:
mysql -u<rootuser> -p<rootpassword> <database> db/08to09.sql mysql -u<rootuser> -p<rootpassword> <database> db/08to09.sql
If you are upgrading from any 0.9.x version like 0.9.6, run this script:
mysql -u<rootuser> -p<rootpassword> <database> db/096to097.sql
Despite the name, it should work for any 0.9.x branch.
Otherwise, go to your StatusNet directory and AFTER YOU MAKE A Otherwise, go to your StatusNet directory and AFTER YOU MAKE A
BACKUP run the rebuilddb.sh script like this: BACKUP run the rebuilddb.sh script like this:
@ -1143,6 +1152,9 @@ ssl: Whether to use SSL for JavaScript files. Default is null, which means
sslserver: SSL server to use when page is HTTPS-encrypted. If sslserver: SSL server to use when page is HTTPS-encrypted. If
unspecified, site ssl server and so on will be used. unspecified, site ssl server and so on will be used.
sslpath: If sslserver if defined, path to use when page is HTTPS-encrypted. sslpath: If sslserver if defined, path to use when page is HTTPS-encrypted.
bustframes: If true, all web pages will break out of framesets. If false,
can comfortably live in a frame or iframe... probably. Default
to true.
xmpp xmpp
---- ----

View File

@ -295,9 +295,8 @@ class NewApplicationAction extends OwnerDesignAction
$app->uploadLogo(); $app->uploadLogo();
} catch (Exception $e) { } catch (Exception $e) {
$app->query('ROLLBACK'); $app->query('ROLLBACK');
// TRANS: Form validation error on New application page when providing an invalid image upload.
$this->showForm(_('Invalid image.')); $this->showForm(_('Invalid image.'));
return; return;
} }
$app->query('COMMIT'); $app->query('COMMIT');

View File

@ -561,10 +561,10 @@ class Notice extends Memcached_DataObject
function blowOnInsert($conversation = false) function blowOnInsert($conversation = false)
{ {
self::blow('profile:notice_ids:%d', $this->profile_id); $this->blowStream('profile:notice_ids:%d', $this->profile_id);
if ($this->isPublic()) { if ($this->isPublic()) {
self::blow('public'); $this->blowStream('public');
} }
// XXX: Before we were blowing the casche only if the notice id // XXX: Before we were blowing the casche only if the notice id
@ -574,7 +574,7 @@ class Notice extends Memcached_DataObject
self::blow('conversation::notice_count:%d', $this->conversation); self::blow('conversation::notice_count:%d', $this->conversation);
if (!empty($this->repeat_of)) { if (!empty($this->repeat_of)) {
self::blow('notice:repeats:%d', $this->repeat_of); $this->blowStream('notice:repeats:%d', $this->repeat_of);
} }
$original = Notice::staticGet('id', $this->repeat_of); $original = Notice::staticGet('id', $this->repeat_of);
@ -582,11 +582,12 @@ class Notice extends Memcached_DataObject
if (!empty($original)) { if (!empty($original)) {
$originalUser = User::staticGet('id', $original->profile_id); $originalUser = User::staticGet('id', $original->profile_id);
if (!empty($originalUser)) { if (!empty($originalUser)) {
self::blow('user:repeats_of_me:%d', $originalUser->id); $this->blowStream('user:repeats_of_me:%d', $originalUser->id);
} }
} }
$profile = Profile::staticGet($this->profile_id); $profile = Profile::staticGet($this->profile_id);
if (!empty($profile)) { if (!empty($profile)) {
$profile->blowNoticeCount(); $profile->blowNoticeCount();
} }
@ -624,6 +625,42 @@ class Notice extends Memcached_DataObject
} }
} }
function blowStream()
{
$c = self::memcache();
if (empty($c)) {
return false;
}
$args = func_get_args();
$format = array_shift($args);
$keyPart = vsprintf($format, $args);
$cacheKey = Cache::key($keyPart);
$c->delete($cacheKey);
// delete the "last" stream, too, if this notice is
// older than the top of that stream
$lastKey = $cacheKey.';last';
$lastStr = $c->get($lastKey);
if ($lastStr !== false) {
$window = explode(',', $lastStr);
$lastID = $window[0];
$lastNotice = Notice::staticGet('id', $lastID);
if (empty($lastNotice) // just weird
|| strtotime($lastNotice->created) >= strtotime($this->created)) {
$c->delete($lastKey);
}
}
}
/** save all urls in the notice to the db /** save all urls in the notice to the db
* *
* follow redirects and save all available file information * follow redirects and save all available file information

View File

@ -335,7 +335,9 @@ class Action extends HTMLOutputter // lawsuit
common_local_url('peopletagautocomplete') . '";'); common_local_url('peopletagautocomplete') . '";');
$this->showScriptMessages(); $this->showScriptMessages();
// Frame-busting code to avoid clickjacking attacks. // Frame-busting code to avoid clickjacking attacks.
$this->inlineScript('if (window.top !== window.self) { window.top.location.href = window.self.location.href; }'); if (common_config('javascript', 'bustframes')) {
$this->inlineScript('if (window.top !== window.self) { window.top.location.href = window.self.location.href; }');
}
Event::handle('EndShowStatusNetScripts', array($this)); Event::handle('EndShowStatusNetScripts', array($this));
Event::handle('EndShowLaconicaScripts', array($this)); Event::handle('EndShowLaconicaScripts', array($this));
} }

View File

@ -83,15 +83,9 @@ class ActivityImporter extends QueueHandler
Event::handle('EndImportActivity', Event::handle('EndImportActivity',
array($user, $author, $activity, $trusted)); array($user, $author, $activity, $trusted));
$done = true; $done = true;
} catch (ClientException $ce) {
common_log(LOG_WARNING, $ce->getMessage());
$done = true;
} catch (ServerException $se) {
common_log(LOG_ERR, $se->getMessage());
$done = false;
} catch (Exception $e) { } catch (Exception $e) {
common_log(LOG_ERR, $e->getMessage()); common_log(LOG_ERR, $e->getMessage());
$done = false; $done = true;
} }
} }
return $done; return $done;

View File

@ -156,7 +156,8 @@ $default =
'javascript' => 'javascript' =>
array('server' => null, array('server' => null,
'path'=> null, 'path'=> null,
'ssl' => null), 'ssl' => null,
'bustframes' => true),
'local' => // To override path/server for themes in 'local' dir (not currently applied to local plugins) 'local' => // To override path/server for themes in 'local' dir (not currently applied to local plugins)
array('server' => null, array('server' => null,
'dir' => null, 'dir' => null,

View File

@ -126,6 +126,15 @@ class Router
return Router::$inst; return Router::$inst;
} }
/**
* Clear the global singleton instance for this class.
* Needed to ensure reset when switching site configurations.
*/
static function clear()
{
Router::$inst = null;
}
function __construct() function __construct()
{ {
if (empty($this->m)) { if (empty($this->m)) {

View File

@ -108,6 +108,8 @@ class StatusNet
*/ */
public static function init($server=null, $path=null, $conffile=null) public static function init($server=null, $path=null, $conffile=null)
{ {
Router::clear();
StatusNet::initDefaults($server, $path); StatusNet::initDefaults($server, $path);
StatusNet::loadConfigFile($conffile); StatusNet::loadConfigFile($conffile);

View File

@ -230,8 +230,23 @@ class Bookmark extends Memcached_DataObject
if (array_key_exists('uri', $options)) { if (array_key_exists('uri', $options)) {
$nb->uri = $options['uri']; $nb->uri = $options['uri'];
} else { } else {
$nb->uri = common_local_url('showbookmark', // FIXME: hacks to work around router bugs in
array('id' => $nb->id)); // queue daemons
$r = Router::get();
$path = $r->build('showbookmark',
array('id' => $nb->id));
if (empty($path)) {
$nb->uri = common_path('bookmark/'.$nb->id, false, false);
} else {
$nb->uri = common_local_url('showbookmark',
array('id' => $nb->id),
null,
null,
false);
}
} }
$nb->insert(); $nb->insert();
@ -313,11 +328,20 @@ class Bookmark extends Memcached_DataObject
$options['uri'] = $nb->uri; $options['uri'] = $nb->uri;
} }
$saved = Notice::saveNew($profile->id, try {
$content, $saved = Notice::saveNew($profile->id,
array_key_exists('source', $options) ? $content,
$options['source'] : 'web', array_key_exists('source', $options) ?
$options); $options['source'] : 'web',
$options);
} catch (Exception $e) {
$nb->delete();
throw $e;
}
if (empty($saved)) {
$nb->delete();
}
return $saved; return $saved;
} }

View File

@ -76,6 +76,12 @@ class DeliciousBackupImporter extends QueueHandler
$doc = $this->importHTML($body); $doc = $this->importHTML($body);
// If we can't parse it, it's no good
if (empty($doc)) {
return true;
}
$dls = $doc->getElementsByTagName('dl'); $dls = $doc->getElementsByTagName('dl');
if ($dls->length != 1) { if ($dls->length != 1) {
@ -110,9 +116,11 @@ class DeliciousBackupImporter extends QueueHandler
case 'dd': case 'dd':
$dd = $child; $dd = $child;
// This <dd> contains a description for the bookmark in if (!empty($dt)) {
// the preceding <dt> node. // This <dd> contains a description for the bookmark in
$saved = $this->importBookmark($user, $dt, $dd); // the preceding <dt> node.
$saved = $this->importBookmark($user, $dt, $dd);
}
$dt = null; $dt = null;
$dd = null; $dd = null;

View File

@ -125,7 +125,10 @@ class Group_message_profile extends Memcached_DataObject
$gmp->insert(); $gmp->insert();
$gmp->notify(); // If it's not for the author, send email notification
if ($gm->from_profile != $profile->id) {
$gmp->notify();
}
return $gmp; return $gmp;
} }

View File

@ -0,0 +1,92 @@
<?php
/**
* StatusNet - the distributed open-source microblogging tool
* Copyright (C) 2011, StatusNet, Inc.
*
* Plugin to put the site notice in the sidebar
*
* PHP version 5
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category Plugin
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @copyright 2011 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
// This check helps protect against security problems;
// your code file can't be executed directly from the web.
exit(1);
}
/**
* Put the site notice in the sidebar
*
* @category General
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @copyright 2011 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/
*/
class SiteNoticeInSidebarPlugin extends Plugin
{
/**
* Function comment
*
* @param
*
* @return
*/
function onStartShowSiteNotice($action)
{
return false;
}
function onStartShowSections($action)
{
$text = common_config('site', 'notice');
if (!empty($text)) {
$sns = new SiteNoticeSection($action, $text);
$sns->show();
}
return true;
}
function onEndShowStyles($action)
{
$action->element('style', null, '#site_notice { width: 100% }');
return true;
}
function onAutoload($cls)
{
$dir = dirname(__FILE__);
switch ($cls)
{
case 'SiteNoticeSection':
include_once $dir . '/'.strtolower($cls).'.php';
return false;
default:
return true;
}
}
}

View File

@ -0,0 +1,67 @@
<?php
/**
* StatusNet - the distributed open-source microblogging tool
* Copyright (C) 2011, StatusNet, Inc.
*
* Site notice section
*
* PHP version 5
*
* 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 Site
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @copyright 2011 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
// This check helps protect against security problems;
// your code file can't be executed directly from the web.
exit(1);
}
/**
* Site notice section
*
* @category Site
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @copyright 2011 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/
*/
class SiteNoticeSection extends Section
{
var $text;
function __construct($action, $text)
{
parent::__construct($action);
$this->text = $text;
}
function title()
{
return _('Site notice');
}
function showContent()
{
$this->out->raw($this->text);
}
}