diff options
author | Evan Prodromou <evan@status.net> | 2010-03-17 09:38:39 -0500 |
---|---|---|
committer | Evan Prodromou <evan@status.net> | 2010-03-17 09:38:39 -0500 |
commit | 4761c07ad8d76f7c34d4db53d32d15e806ba1e88 (patch) | |
tree | eb3d78ccde1778037165c92b6ec36c7465b54345 /lib | |
parent | f21f78364a9cbde2ca535a3983b384707ad097ae (diff) | |
parent | f62b8a80cf33ac8529d0736c51dc060a9d235369 (diff) |
Merge branch 'testing' of git@gitorious.org:statusnet/mainline into testing
Diffstat (limited to 'lib')
-rw-r--r-- | lib/activity.php | 29 | ||||
-rw-r--r-- | lib/common.php | 12 | ||||
-rw-r--r-- | lib/deluserqueuehandler.php | 95 | ||||
-rw-r--r-- | lib/queuemanager.php | 3 | ||||
-rw-r--r-- | lib/router.php | 6 | ||||
-rw-r--r-- | lib/userprofile.php | 11 |
6 files changed, 131 insertions, 25 deletions
diff --git a/lib/activity.php b/lib/activity.php index 125d391b0..d84eabf7c 100644 --- a/lib/activity.php +++ b/lib/activity.php @@ -457,13 +457,13 @@ class ActivityUtils // slavishly following http://atompub.org/rfc4287.html#rfc.section.4.1.3.3 - if ($type == 'text') { + if (empty($type) || $type == 'text') { return $contentEl->textContent; } else if ($type == 'html') { $text = $contentEl->textContent; return htmlspecialchars_decode($text, ENT_QUOTES); } else if ($type == 'xhtml') { - $divEl = ActivityUtils::child($contentEl, 'div'); + $divEl = ActivityUtils::child($contentEl, 'div', 'http://www.w3.org/1999/xhtml'); if (empty($divEl)) { return null; } @@ -476,7 +476,7 @@ class ActivityUtils $text .= $doc->saveXML($child); } return trim($text); - } else if (in_array(array('text/xml', 'application/xml'), $type) || + } else if (in_array($type, array('text/xml', 'application/xml')) || preg_match('#(+|/)xml$#', $type)) { throw new ClientException(_("Can't handle embedded XML content yet.")); } else if (strncasecmp($type, 'text/', 5)) { @@ -681,9 +681,16 @@ class ActivityObject if ($this->type == self::PERSON || $this->type == self::GROUP) { $this->displayName = $this->title; - $avatars = ActivityUtils::getLinks($element, 'avatar'); - foreach ($avatars as $link) { - $this->avatarLinks[] = new AvatarLink($link); + $photos = ActivityUtils::getLinks($element, 'photo'); + if (count($photos)) { + foreach ($photos as $link) { + $this->avatarLinks[] = new AvatarLink($link); + } + } else { + $avatars = ActivityUtils::getLinks($element, 'avatar'); + foreach ($avatars as $link) { + $this->avatarLinks[] = new AvatarLink($link); + } } $this->poco = new PoCo($element); @@ -1076,15 +1083,11 @@ class Activity $this->entry = $entry; - // @fixme Don't send in a DOMDocument + // Insist on a feed's root DOMElement; don't allow a DOMDocument if ($feed instanceof DOMDocument) { - common_log( - LOG_WARNING, - 'Activity::__construct() - ' - . 'DOMDocument passed in for feed by mistake. ' - . "Expecting a 'feed' DOMElement." + throw new ClientException( + _("Expecting a root feed element but got a whole XML document.") ); - $feed = $feed->getElementsByTagName('feed')->item(0); } $this->feed = $feed; diff --git a/lib/common.php b/lib/common.php index 047dc5a7b..5d53270e3 100644 --- a/lib/common.php +++ b/lib/common.php @@ -71,7 +71,6 @@ if (!function_exists('dl')) { # global configuration object require_once('PEAR.php'); -require_once('PEAR/Exception.php'); require_once('DB/DataObject.php'); require_once('DB/DataObject/Cast.php'); # for dates @@ -129,17 +128,6 @@ require_once INSTALLDIR.'/lib/activity.php'; require_once INSTALLDIR.'/lib/clientexception.php'; require_once INSTALLDIR.'/lib/serverexception.php'; - -//set PEAR error handling to use regular PHP exceptions -function PEAR_ErrorToPEAR_Exception($err) -{ - if ($err->getCode()) { - throw new PEAR_Exception($err->getMessage(), $err->getCode()); - } - throw new PEAR_Exception($err->getMessage()); -} -PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, 'PEAR_ErrorToPEAR_Exception'); - try { StatusNet::init(@$server, @$path, @$conffile); } catch (NoConfigException $e) { diff --git a/lib/deluserqueuehandler.php b/lib/deluserqueuehandler.php new file mode 100644 index 000000000..4a1233a5e --- /dev/null +++ b/lib/deluserqueuehandler.php @@ -0,0 +1,95 @@ +<?php +/* + * StatusNet - the 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/>. + */ + +/** + * Background job to delete prolific users without disrupting front-end too much. + * + * Up to 50 messages are deleted on each run through; when all messages are gone, + * the actual account is deleted. + * + * @package QueueHandler + * @maintainer Brion Vibber <brion@status.net> + */ + +class DelUserQueueHandler extends QueueHandler +{ + const DELETION_WINDOW = 50; + + public function transport() + { + return 'deluser'; + } + + public function handle($user) + { + if (!($user instanceof User)) { + common_log(LOG_ERR, "Got a bogus user, not deleting"); + return true; + } + + $user = User::staticGet('id', $user->id); + if (!$user) { + common_log(LOG_INFO, "User {$user->nickname} was deleted before we got here."); + return true; + } + + if (!$user->hasRole(Profile_role::DELETED)) { + common_log(LOG_INFO, "User {$user->nickname} is not pending deletion; aborting."); + return true; + } + + $notice = $this->getNextBatch($user); + if ($notice->N) { + common_log(LOG_INFO, "Deleting next {$notice->N} notices by {$user->nickname}"); + while ($notice->fetch()) { + $del = clone($notice); + $del->delete(); + } + + // @todo improve reliability in case we died during the above deletions + // with a fatal error. If the job is lost, we should perform some kind + // of garbage collection later. + + // Queue up the next batch. + $qm = QueueManager::get(); + $qm->enqueue($user, 'deluser'); + } else { + // Out of notices? Let's finish deleting this guy! + $user->delete(); + common_log(LOG_INFO, "User $user->id $user->nickname deleted."); + return true; + } + + return true; + } + + /** + * Fetch the next self::DELETION_WINDOW messages for this user. + * @return Notice + */ + protected function getNextBatch(User $user) + { + $notice = new Notice(); + $notice->profile_id = $user->id; + $notice->limit(self::DELETION_WINDOW); + $notice->find(); + return $notice; + } + +} diff --git a/lib/queuemanager.php b/lib/queuemanager.php index 87bd356aa..0829c8a8b 100644 --- a/lib/queuemanager.php +++ b/lib/queuemanager.php @@ -264,6 +264,9 @@ abstract class QueueManager extends IoManager $this->connect('sms', 'SmsQueueHandler'); } + // Background user management tasks... + $this->connect('deluser', 'DelUserQueueHandler'); + // Broadcasting profile updates to OMB remote subscribers $this->connect('profile', 'ProfileQueueHandler'); diff --git a/lib/router.php b/lib/router.php index 706120e0b..a48ee875e 100644 --- a/lib/router.php +++ b/lib/router.php @@ -628,6 +628,12 @@ class Router array('action' => 'ApiTimelineTag', 'format' => '(xmljson|rss|atom)')); + // media related + $m->connect( + 'api/statusnet/media/upload', + array('action' => 'ApiMediaUpload') + ); + // search $m->connect('api/search.atom', array('action' => 'twitapisearchatom')); $m->connect('api/search.json', array('action' => 'twitapisearchjson')); diff --git a/lib/userprofile.php b/lib/userprofile.php index 8464c2446..2c3b1ea45 100644 --- a/lib/userprofile.php +++ b/lib/userprofile.php @@ -228,6 +228,17 @@ class UserProfile extends Widget function showEntityActions() { + if ($this->profile->hasRole(Profile_role::DELETED)) { + $this->out->elementStart('div', 'entity_actions'); + $this->out->element('h2', null, _('User actions')); + $this->out->elementStart('ul'); + $this->out->elementStart('p', array('class' => 'profile_deleted')); + $this->out->text(_('User deletion in progress...')); + $this->out->elementEnd('p'); + $this->out->elementEnd('ul'); + $this->out->elementEnd('div'); + return; + } if (Event::handle('StartProfilePageActionsSection', array(&$this->out, $this->profile))) { $cur = common_current_user(); |