Merge branch 'master' into 0.9.x
This commit is contained in:
commit
753bc7302a
93
README
93
README
@ -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:
|
||||||
|
|
||||||
|
@ -322,8 +322,11 @@ class ApiTimelineUserAction extends ApiBareAuthAction
|
|||||||
$this->clientError(_('Atom post must not be empty.'));
|
$this->clientError(_('Atom post must not be empty.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$dom = DOMDocument::loadXML($xml);
|
$old = error_reporting(error_reporting() & ~(E_WARNING | E_NOTICE));
|
||||||
if (!$dom) {
|
$dom = new DOMDocument();
|
||||||
|
$ok = $dom->loadXML($xml);
|
||||||
|
error_reporting($old);
|
||||||
|
if (!$ok) {
|
||||||
// TRANS: Client error displayed attempting to post an API that is not well-formed XML.
|
// TRANS: Client error displayed attempting to post an API that is not well-formed XML.
|
||||||
$this->clientError(_('Atom post must be well-formed XML.'));
|
$this->clientError(_('Atom post must be well-formed XML.'));
|
||||||
}
|
}
|
||||||
|
@ -282,7 +282,11 @@ class RecoverpasswordAction extends Action
|
|||||||
$user = User::staticGet('email', common_canonical_email($nore));
|
$user = User::staticGet('email', common_canonical_email($nore));
|
||||||
|
|
||||||
if (!$user) {
|
if (!$user) {
|
||||||
|
try {
|
||||||
$user = User::staticGet('nickname', common_canonical_nickname($nore));
|
$user = User::staticGet('nickname', common_canonical_nickname($nore));
|
||||||
|
} catch (NicknameException $e) {
|
||||||
|
// invalid
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# See if it's an unconfirmed email address
|
# See if it's an unconfirmed email address
|
||||||
|
@ -445,19 +445,19 @@ 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
|
||||||
// was not the root of the conversation. What to do now?
|
// was not the root of the conversation. What to do now?
|
||||||
|
|
||||||
self::blow('notice:conversation_ids:%d', $this->conversation);
|
$this->blowStream('notice:conversation_ids:%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);
|
||||||
@ -465,11 +465,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();
|
||||||
}
|
}
|
||||||
@ -490,6 +491,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
|
||||||
|
@ -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;
|
||||||
|
@ -22,13 +22,13 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
|
|||||||
//exit with 200 response, if this is checking fancy from the installer
|
//exit with 200 response, if this is checking fancy from the installer
|
||||||
if (isset($_REQUEST['p']) && $_REQUEST['p'] == 'check-fancy') { exit; }
|
if (isset($_REQUEST['p']) && $_REQUEST['p'] == 'check-fancy') { exit; }
|
||||||
|
|
||||||
define('STATUSNET_BASE_VERSION', '0.9.8');
|
define('STATUSNET_BASE_VERSION', '0.9.7');
|
||||||
define('STATUSNET_LIFECYCLE', 'dev'); // 'dev', 'alpha[0-9]+', 'beta[0-9]+', 'rc[0-9]+', 'release'
|
define('STATUSNET_LIFECYCLE', 'fix1'); // 'dev', 'alpha[0-9]+', 'beta[0-9]+', 'rc[0-9]+', '' for release
|
||||||
define('STATUSNET_VERSION', STATUSNET_BASE_VERSION . STATUSNET_LIFECYCLE);
|
define('STATUSNET_VERSION', STATUSNET_BASE_VERSION . STATUSNET_LIFECYCLE);
|
||||||
|
|
||||||
define('LACONICA_VERSION', STATUSNET_VERSION); // compatibility
|
define('LACONICA_VERSION', STATUSNET_VERSION); // compatibility
|
||||||
|
|
||||||
define('STATUSNET_CODENAME', 'Letter Never Sent');
|
define('STATUSNET_CODENAME', 'World Leader Pretend');
|
||||||
|
|
||||||
define('AVATAR_PROFILE_SIZE', 96);
|
define('AVATAR_PROFILE_SIZE', 96);
|
||||||
define('AVATAR_STREAM_SIZE', 48);
|
define('AVATAR_STREAM_SIZE', 48);
|
||||||
|
@ -102,7 +102,7 @@ class NoticeSection extends Section
|
|||||||
$this->out->elementEnd('p');
|
$this->out->elementEnd('p');
|
||||||
|
|
||||||
$this->out->elementStart('div', 'entry_content');
|
$this->out->elementStart('div', 'entry_content');
|
||||||
get_class('NoticeList');
|
class_exists('NoticeList');
|
||||||
$nli = new NoticeListItem($notice, $this->out);
|
$nli = new NoticeListItem($notice, $this->out);
|
||||||
$nli->showNoticeLink();
|
$nli->showNoticeLink();
|
||||||
$this->out->elementEnd('div');
|
$this->out->elementEnd('div');
|
||||||
|
@ -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)) {
|
||||||
|
@ -107,6 +107,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);
|
||||||
|
|
||||||
|
@ -238,8 +238,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
|
||||||
|
// queue daemons
|
||||||
|
|
||||||
|
$r = Router::get();
|
||||||
|
|
||||||
|
$path = $r->build('showbookmark',
|
||||||
array('id' => $nb->id));
|
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();
|
||||||
@ -314,11 +329,20 @@ class Bookmark extends Memcached_DataObject
|
|||||||
$options['uri'] = $nb->uri;
|
$options['uri'] = $nb->uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
$saved = Notice::saveNew($profile->id,
|
$saved = Notice::saveNew($profile->id,
|
||||||
$content,
|
$content,
|
||||||
array_key_exists('source', $options) ?
|
array_key_exists('source', $options) ?
|
||||||
$options['source'] : 'web',
|
$options['source'] : 'web',
|
||||||
$options);
|
$options);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$nb->delete();
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($saved)) {
|
||||||
|
$nb->delete();
|
||||||
|
}
|
||||||
|
|
||||||
return $saved;
|
return $saved;
|
||||||
}
|
}
|
||||||
|
@ -450,7 +450,7 @@ class BookmarkPlugin extends Plugin
|
|||||||
|
|
||||||
function onPluginVersion(&$versions)
|
function onPluginVersion(&$versions)
|
||||||
{
|
{
|
||||||
$versions[] = array('name' => 'Sample',
|
$versions[] = array('name' => 'Bookmark',
|
||||||
'version' => self::VERSION,
|
'version' => self::VERSION,
|
||||||
'author' => 'Evan Prodromou',
|
'author' => 'Evan Prodromou',
|
||||||
'homepage' => 'http://status.net/wiki/Plugin:Bookmark',
|
'homepage' => 'http://status.net/wiki/Plugin:Bookmark',
|
||||||
|
@ -79,6 +79,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) {
|
||||||
@ -112,9 +118,11 @@ class DeliciousBackupImporter extends QueueHandler
|
|||||||
case 'dd':
|
case 'dd':
|
||||||
$dd = $child;
|
$dd = $child;
|
||||||
|
|
||||||
|
if (!empty($dt)) {
|
||||||
// This <dd> contains a description for the bookmark in
|
// This <dd> contains a description for the bookmark in
|
||||||
// the preceding <dt> node.
|
// the preceding <dt> node.
|
||||||
$saved = $this->importBookmark($user, $dt, $dd);
|
$saved = $this->importBookmark($user, $dt, $dd);
|
||||||
|
}
|
||||||
|
|
||||||
$dt = null;
|
$dt = null;
|
||||||
$dd = null;
|
$dd = null;
|
||||||
|
@ -526,7 +526,7 @@ ENDOFSCRIPT;
|
|||||||
*/
|
*/
|
||||||
function onEndFavorNotice(Profile $profile, Notice $notice)
|
function onEndFavorNotice(Profile $profile, Notice $notice)
|
||||||
{
|
{
|
||||||
$client = new Facebookclient($notice);
|
$client = new Facebookclient($notice, $profile);
|
||||||
$client->like();
|
$client->like();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -542,7 +542,7 @@ ENDOFSCRIPT;
|
|||||||
*/
|
*/
|
||||||
function onEndDisfavorNotice(Profile $profile, Notice $notice)
|
function onEndDisfavorNotice(Profile $profile, Notice $notice)
|
||||||
{
|
{
|
||||||
$client = new Facebookclient($notice);
|
$client = new Facebookclient($notice, $profile);
|
||||||
$client->unLike();
|
$client->unLike();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -48,7 +48,12 @@ class Facebookclient
|
|||||||
protected $notice = null; // The user's notice
|
protected $notice = null; // The user's notice
|
||||||
protected $user = null; // Sender of the notice
|
protected $user = null; // Sender of the notice
|
||||||
|
|
||||||
function __construct($notice)
|
/**
|
||||||
|
*
|
||||||
|
* @param Notice $notice the notice to manipulate
|
||||||
|
* @param Profile $profile local user to act as; if left empty, the notice's poster will be used.
|
||||||
|
*/
|
||||||
|
function __construct($notice, $profile=null)
|
||||||
{
|
{
|
||||||
$this->facebook = self::getFacebook();
|
$this->facebook = self::getFacebook();
|
||||||
|
|
||||||
@ -60,8 +65,9 @@ class Facebookclient
|
|||||||
|
|
||||||
$this->notice = $notice;
|
$this->notice = $notice;
|
||||||
|
|
||||||
|
$profile_id = $profile ? $profile->id : $notice->profile_id;
|
||||||
$this->flink = Foreign_link::getByUserID(
|
$this->flink = Foreign_link::getByUserID(
|
||||||
$notice->profile_id,
|
$profile_id,
|
||||||
FACEBOOK_SERVICE
|
FACEBOOK_SERVICE
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -127,7 +127,10 @@ class Group_message_profile extends Memcached_DataObject
|
|||||||
|
|
||||||
$gmp->insert();
|
$gmp->insert();
|
||||||
|
|
||||||
|
// If it's not for the author, send email notification
|
||||||
|
if ($gm->from_profile != $profile->id) {
|
||||||
$gmp->notify();
|
$gmp->notify();
|
||||||
|
}
|
||||||
|
|
||||||
return $gmp;
|
return $gmp;
|
||||||
}
|
}
|
||||||
@ -156,9 +159,7 @@ class Group_message_profile extends Memcached_DataObject
|
|||||||
|
|
||||||
// TRANS: Subject for direct-message notification email.
|
// TRANS: Subject for direct-message notification email.
|
||||||
// TRANS: %s is the sending user's nickname.
|
// TRANS: %s is the sending user's nickname.
|
||||||
$subject = sprintf(_('New private message from %s to group %s'), $from->nickname, $group->nickname);
|
$subject = sprintf(_('New private message from %s to group %s'), $from_profile->nickname, $group->nickname);
|
||||||
|
|
||||||
$from_profile = $from->getProfile();
|
|
||||||
|
|
||||||
// TRANS: Body for direct-message notification email.
|
// TRANS: Body for direct-message notification email.
|
||||||
// TRANS: %1$s is the sending user's long name, %2$s is the sending user's nickname,
|
// TRANS: %1$s is the sending user's long name, %2$s is the sending user's nickname,
|
||||||
@ -174,13 +175,13 @@ class Group_message_profile extends Memcached_DataObject
|
|||||||
"With kind regards,\n".
|
"With kind regards,\n".
|
||||||
"%6\$s\n"),
|
"%6\$s\n"),
|
||||||
$from_profile->getBestName(),
|
$from_profile->getBestName(),
|
||||||
$from->nickname,
|
$from_profile->nickname,
|
||||||
$group->nickname,
|
$group->nickname,
|
||||||
$this->content,
|
$gm->content,
|
||||||
common_local_url('newmessage', array('to' => $from->id)),
|
common_local_url('newmessage', array('to' => $from_profile->id)),
|
||||||
common_config('site', 'name'));
|
common_config('site', 'name'));
|
||||||
|
|
||||||
$headers = _mail_prepare_headers('message', $to->nickname, $from->nickname);
|
$headers = _mail_prepare_headers('message', $to->nickname, $from_profile->nickname);
|
||||||
|
|
||||||
common_switch_locale();
|
common_switch_locale();
|
||||||
|
|
||||||
|
@ -129,9 +129,9 @@ class ModPlusPlugin extends Plugin
|
|||||||
* Currently only adds output for remote profiles, nothing for local users.
|
* Currently only adds output for remote profiles, nothing for local users.
|
||||||
*
|
*
|
||||||
* @param HTMLOutputter $out
|
* @param HTMLOutputter $out
|
||||||
* @param Profile $profile
|
* @param Profile $profile (may also be an ArrayWrapper... sigh)
|
||||||
*/
|
*/
|
||||||
protected function showProfileOptions(HTMLOutputter $out, Profile $profile)
|
protected function showProfileOptions(HTMLOutputter $out, $profile)
|
||||||
{
|
{
|
||||||
$isRemote = !(User::staticGet('id', $profile->id));
|
$isRemote = !(User::staticGet('id', $profile->id));
|
||||||
if ($isRemote) {
|
if ($isRemote) {
|
||||||
|
92
plugins/SiteNoticeInSidebar/SiteNoticeInSidebarPlugin.php
Normal file
92
plugins/SiteNoticeInSidebar/SiteNoticeInSidebarPlugin.php
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
67
plugins/SiteNoticeInSidebar/sitenoticesection.php
Normal file
67
plugins/SiteNoticeInSidebar/sitenoticesection.php
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
@ -320,7 +320,20 @@ function process_error($e, $flink, $notice)
|
|||||||
|
|
||||||
common_log(LOG_WARNING, $logmsg);
|
common_log(LOG_WARNING, $logmsg);
|
||||||
|
|
||||||
|
// http://dev.twitter.com/pages/responses_errors
|
||||||
switch($code) {
|
switch($code) {
|
||||||
|
case 400:
|
||||||
|
// Probably invalid data (bad Unicode chars or coords) that
|
||||||
|
// cannot be resolved by just sending again.
|
||||||
|
//
|
||||||
|
// It could also be rate limiting, but retrying immediately
|
||||||
|
// won't help much with that, so we'll discard for now.
|
||||||
|
// If a facility for retrying things later comes up in future,
|
||||||
|
// we can detect the rate-limiting headers and use that.
|
||||||
|
//
|
||||||
|
// Discard the message permanently.
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
case 401:
|
case 401:
|
||||||
// Probably a revoked or otherwise bad access token - nuke!
|
// Probably a revoked or otherwise bad access token - nuke!
|
||||||
remove_twitter_link($flink);
|
remove_twitter_link($flink);
|
||||||
@ -330,6 +343,13 @@ function process_error($e, $flink, $notice)
|
|||||||
// User has exceeder her rate limit -- toss the notice
|
// User has exceeder her rate limit -- toss the notice
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
case 404:
|
||||||
|
// Resource not found. Shouldn't happen much on posting,
|
||||||
|
// but just in case!
|
||||||
|
//
|
||||||
|
// Consider it a matter for tossing the notice.
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
||||||
// For every other case, it's probably some flakiness so try
|
// For every other case, it's probably some flakiness so try
|
||||||
|
Loading…
Reference in New Issue
Block a user