From 98f0d970da98e5b6de18972d033320a191152eb4 Mon Sep 17 00:00:00 2001 From: Zachary Copley Date: Tue, 20 Apr 2010 15:01:23 -0700 Subject: [PATCH 01/14] Update release notes and version number for 0.9.2 --- README | 53 ++++++++++++++++++++++++-------------------------- lib/common.php | 2 +- 2 files changed, 26 insertions(+), 29 deletions(-) diff --git a/README b/README index c687cb240a..98ebe15066 100644 --- a/README +++ b/README @@ -2,8 +2,8 @@ README ------ -StatusNet 0.9.1 ("Everybody Hurts") -28 Mar 2010 +StatusNet 0.9.2 ("King of Birds") +21 Apr 2010 This is the README file for StatusNet, the Open Source microblogging platform. It includes installation instructions, descriptions of @@ -77,7 +77,7 @@ for additional terms. New this version ================ -This is a minor bug and feature release since version 0.9.0 released 4 +This is a minor bug and feature release since version 0.9.1 released 28 March 2010. Because of fixes to OStatus bugs, it is highly recommended that all @@ -85,26 +85,23 @@ public sites upgrade to the new version immediately. Notable changes this version: -- Twitter bridge truncates and links back to original for long - notices. -- Changed "Home" link in main menu to "Personal". -- A new memcached plugin (using pecl/memcached versus pecl/memcache) -- Opt-in subscription to update@status.net -- Script to run commands on behalf of a user. -- Better Web UI for long notices. -- A plugin to open external links in their own window or tab -- Fixes to Salmon protocol for compatibility with other systems. -- Updates to latest ActivityStreams definition. -- Twitpic-compatible API for image upload. -- Background deletion of user accounts. -- Better support for HTTP basic authentication with CGI/FastCGI -- Better discovery on OStatus -- Support for PuSH-enabled RSS 2.0 feeds -- OpenID-only mode -- OpenID blacklist/whitelist -- OStatus unit tests +- Fixed email notifications for @-replies that come in via OStatus +- OStatus related Fixes to the cloudy theme +- Pass geo locations over Twitter bridge (will only be used if enabled on the Twitter side) +- scripts/showplugins.php - script to dump the list of activated plugins and their settings +- scripts/fixup_blocks.php - script to finds any stray subscriptions in violation of blocks, and removes them +- Allow blocking someone who's not currently subscribed to you (prevents seeing @-replies from them, or them subbing to you in future) +- Default 2-second timeout on Geonames web service lookups +- Improved localization for plugins +- New anti-spam measures: added nofollow rels to group members list, subscribers list +- Shared cache key option for Geonames plugin (lets multi-instance sites share their cached geoname lookups) +- Stability fixes to the TwitterStatusFetcher +- If user allows location sharing but turned off browser location use profile location +- Improved group listing via the API +- Improved FOAF output +- Several other bugfixes -A full changelog is available at http://status.net/wiki/StatusNet_0.9.1. +A full changelog is available at http://status.net/wiki/StatusNet_0.9.2. Prerequisites ============= @@ -216,9 +213,9 @@ especially if you've previously installed PHP/MySQL packages. 1. Unpack the tarball you downloaded on your Web server. Usually a command like this will work: - tar zxf statusnet-0.9.1.tar.gz + tar zxf statusnet-0.9.2.tar.gz - ...which will make a statusnet-0.9.1 subdirectory in your current + ...which will make a statusnet-0.9.2 subdirectory in your current 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 files to the server.) @@ -226,7 +223,7 @@ especially if you've previously installed PHP/MySQL packages. 2. Move the tarball to a directory of your choosing in your Web root directory. Usually something like this will work: - mv statusnet-0.9.1 /var/www/statusnet + mv statusnet-0.9.2 /var/www/statusnet This will make your StatusNet instance available in the statusnet path of your server, like "http://example.net/statusnet". "microblog" or @@ -641,7 +638,7 @@ with this situation. 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 want to upgrade and keep your existing data. There is no automated -upgrade procedure in StatusNet 0.9.1. Try these step-by-step +upgrade procedure in StatusNet 0.9.2. Try these step-by-step instructions; read to the end first before trying them. 0. Download StatusNet and set up all the prerequisites as if you were @@ -662,7 +659,7 @@ instructions; read to the end first before trying them. 5. Once all writing processes to your site are turned off, make a final backup of the Web directory and database. 6. Move your StatusNet directory to a backup spot, like "statusnet.bak". -7. Unpack your StatusNet 0.9.1 tarball and move it to "statusnet" or +7. Unpack your StatusNet 0.9.2 tarball and move it to "statusnet" or wherever your code used to be. 8. Copy the config.php file and avatar directory from your old directory to your new directory. @@ -1499,7 +1496,7 @@ repository (see below), and you get a compilation error ("unexpected T_STRING") in the browser, check to see that you don't have any conflicts in your code. -If you upgraded to StatusNet 0.9.1 without reading the "Notice +If you upgraded to StatusNet 0.9.2 without reading the "Notice inboxes" section above, and all your users' 'Personal' tabs are empty, read the "Notice inboxes" section above. diff --git a/lib/common.php b/lib/common.php index 8d2e6b420b..b29719b75c 100644 --- a/lib/common.php +++ b/lib/common.php @@ -22,7 +22,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } //exit with 200 response, if this is checking fancy from the installer if (isset($_REQUEST['p']) && $_REQUEST['p'] == 'check-fancy') { exit; } -define('STATUSNET_VERSION', '0.9.1'); +define('STATUSNET_VERSION', '0.9.2'); define('LACONICA_VERSION', STATUSNET_VERSION); // compatibility define('STATUSNET_CODENAME', 'Everybody Hurts'); From 1d94b08efcda56fa5efdef19721bcef21410177a Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Wed, 21 Apr 2010 16:24:15 +0200 Subject: [PATCH 02/14] Revert "Update release notes and version number for 0.9.2" This reverts commit 98f0d970da98e5b6de18972d033320a191152eb4. Per xopher we're not yet ready to push 0.9.2 theme directories live; we also haven't merged down various things from testing that need to be in the release such as installer fixes. --- README | 53 ++++++++++++++++++++++++++------------------------ lib/common.php | 2 +- 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/README b/README index 98ebe15066..c687cb240a 100644 --- a/README +++ b/README @@ -2,8 +2,8 @@ README ------ -StatusNet 0.9.2 ("King of Birds") -21 Apr 2010 +StatusNet 0.9.1 ("Everybody Hurts") +28 Mar 2010 This is the README file for StatusNet, the Open Source microblogging platform. It includes installation instructions, descriptions of @@ -77,7 +77,7 @@ for additional terms. New this version ================ -This is a minor bug and feature release since version 0.9.1 released 28 +This is a minor bug and feature release since version 0.9.0 released 4 March 2010. Because of fixes to OStatus bugs, it is highly recommended that all @@ -85,23 +85,26 @@ public sites upgrade to the new version immediately. Notable changes this version: -- Fixed email notifications for @-replies that come in via OStatus -- OStatus related Fixes to the cloudy theme -- Pass geo locations over Twitter bridge (will only be used if enabled on the Twitter side) -- scripts/showplugins.php - script to dump the list of activated plugins and their settings -- scripts/fixup_blocks.php - script to finds any stray subscriptions in violation of blocks, and removes them -- Allow blocking someone who's not currently subscribed to you (prevents seeing @-replies from them, or them subbing to you in future) -- Default 2-second timeout on Geonames web service lookups -- Improved localization for plugins -- New anti-spam measures: added nofollow rels to group members list, subscribers list -- Shared cache key option for Geonames plugin (lets multi-instance sites share their cached geoname lookups) -- Stability fixes to the TwitterStatusFetcher -- If user allows location sharing but turned off browser location use profile location -- Improved group listing via the API -- Improved FOAF output -- Several other bugfixes +- Twitter bridge truncates and links back to original for long + notices. +- Changed "Home" link in main menu to "Personal". +- A new memcached plugin (using pecl/memcached versus pecl/memcache) +- Opt-in subscription to update@status.net +- Script to run commands on behalf of a user. +- Better Web UI for long notices. +- A plugin to open external links in their own window or tab +- Fixes to Salmon protocol for compatibility with other systems. +- Updates to latest ActivityStreams definition. +- Twitpic-compatible API for image upload. +- Background deletion of user accounts. +- Better support for HTTP basic authentication with CGI/FastCGI +- Better discovery on OStatus +- Support for PuSH-enabled RSS 2.0 feeds +- OpenID-only mode +- OpenID blacklist/whitelist +- OStatus unit tests -A full changelog is available at http://status.net/wiki/StatusNet_0.9.2. +A full changelog is available at http://status.net/wiki/StatusNet_0.9.1. Prerequisites ============= @@ -213,9 +216,9 @@ especially if you've previously installed PHP/MySQL packages. 1. Unpack the tarball you downloaded on your Web server. Usually a command like this will work: - tar zxf statusnet-0.9.2.tar.gz + tar zxf statusnet-0.9.1.tar.gz - ...which will make a statusnet-0.9.2 subdirectory in your current + ...which will make a statusnet-0.9.1 subdirectory in your current 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 files to the server.) @@ -223,7 +226,7 @@ especially if you've previously installed PHP/MySQL packages. 2. Move the tarball to a directory of your choosing in your Web root directory. Usually something like this will work: - mv statusnet-0.9.2 /var/www/statusnet + mv statusnet-0.9.1 /var/www/statusnet This will make your StatusNet instance available in the statusnet path of your server, like "http://example.net/statusnet". "microblog" or @@ -638,7 +641,7 @@ with this situation. 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 want to upgrade and keep your existing data. There is no automated -upgrade procedure in StatusNet 0.9.2. Try these step-by-step +upgrade procedure in StatusNet 0.9.1. Try these step-by-step instructions; read to the end first before trying them. 0. Download StatusNet and set up all the prerequisites as if you were @@ -659,7 +662,7 @@ instructions; read to the end first before trying them. 5. Once all writing processes to your site are turned off, make a final backup of the Web directory and database. 6. Move your StatusNet directory to a backup spot, like "statusnet.bak". -7. Unpack your StatusNet 0.9.2 tarball and move it to "statusnet" or +7. Unpack your StatusNet 0.9.1 tarball and move it to "statusnet" or wherever your code used to be. 8. Copy the config.php file and avatar directory from your old directory to your new directory. @@ -1496,7 +1499,7 @@ repository (see below), and you get a compilation error ("unexpected T_STRING") in the browser, check to see that you don't have any conflicts in your code. -If you upgraded to StatusNet 0.9.2 without reading the "Notice +If you upgraded to StatusNet 0.9.1 without reading the "Notice inboxes" section above, and all your users' 'Personal' tabs are empty, read the "Notice inboxes" section above. diff --git a/lib/common.php b/lib/common.php index b29719b75c..8d2e6b420b 100644 --- a/lib/common.php +++ b/lib/common.php @@ -22,7 +22,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } //exit with 200 response, if this is checking fancy from the installer if (isset($_REQUEST['p']) && $_REQUEST['p'] == 'check-fancy') { exit; } -define('STATUSNET_VERSION', '0.9.2'); +define('STATUSNET_VERSION', '0.9.1'); define('LACONICA_VERSION', STATUSNET_VERSION); // compatibility define('STATUSNET_CODENAME', 'Everybody Hurts'); From e28214bfe91b23fe5e463d6e56152218f0769910 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Wed, 21 Apr 2010 18:11:29 -0700 Subject: [PATCH 03/14] fix reference error in RSSCloud plugin --- plugins/RSSCloud/RSSCloudPlugin.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/RSSCloud/RSSCloudPlugin.php b/plugins/RSSCloud/RSSCloudPlugin.php index 9f444c8bba..661c32141f 100644 --- a/plugins/RSSCloud/RSSCloudPlugin.php +++ b/plugins/RSSCloud/RSSCloudPlugin.php @@ -100,12 +100,12 @@ class RSSCloudPlugin extends Plugin * * Hook for RouterInitialized event. * - * @param Mapper &$m URL parser and mapper + * @param Mapper $m URL parser and mapper * * @return boolean hook return */ - function onRouterInitialized(&$m) + function onRouterInitialized($m) { $m->connect('/main/rsscloud/request_notify', array('action' => 'RSSCloudRequestNotify')); From a129c455a2e102c4276a95694a8fb0ece830232b Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Wed, 21 Apr 2010 18:19:16 -0700 Subject: [PATCH 04/14] Fix exceptions with bad gravatar URLs --- plugins/OStatus/classes/Ostatus_profile.php | 30 ++++++++++++++------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/plugins/OStatus/classes/Ostatus_profile.php b/plugins/OStatus/classes/Ostatus_profile.php index e3b3daa2c5..5d3f37cd07 100644 --- a/plugins/OStatus/classes/Ostatus_profile.php +++ b/plugins/OStatus/classes/Ostatus_profile.php @@ -1001,7 +1001,7 @@ class Ostatus_profile extends Memcached_DataObject return; } if (!common_valid_http_url($url)) { - throw new ServerException(_m("Invalid avatar URL %s"), $url); + throw new ServerException(sprintf(_m("Invalid avatar URL %s"), $url)); } if ($this->isGroup()) { @@ -1303,15 +1303,23 @@ class Ostatus_profile extends Memcached_DataObject $ok = $oprofile->insert(); - if ($ok) { - $avatar = self::getActivityObjectAvatar($object, $hints); - if ($avatar) { - $oprofile->updateAvatar($avatar); - } - return $oprofile; - } else { + if (!$ok) { throw new ServerException("Can't save OStatus profile"); } + + $avatar = self::getActivityObjectAvatar($object, $hints); + + if ($avatar) { + try { + $oprofile->updateAvatar($avatar); + } catch (Exception $ex) { + // Profile is saved, but Avatar is messed up. We're + // just going to continue. + common_log(LOG_WARNING, "Exception saving OStatus profile avatar: ". $ex->getMessage()); + } + } + + return $oprofile; } /** @@ -1330,7 +1338,11 @@ class Ostatus_profile extends Memcached_DataObject } $avatar = self::getActivityObjectAvatar($object, $hints); if ($avatar) { - $this->updateAvatar($avatar); + try { + $this->updateAvatar($avatar); + } catch (Exception $ex) { + common_log(LOG_WARNING, "Exception saving OStatus profile avatar: " . $ex->getMessage()); + } } } From fd9d520aeb52f7f3a3fe7c242fbe16078de1bc6e Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Thu, 22 Apr 2010 06:14:40 +0200 Subject: [PATCH 05/14] OStatus: CLI script to force a renewal on the given PuSH subscription. May help when we get out of sync with the hub. php plugins/OStatus/scripts/resub-feed.php -smysite http://example.com/some/atom/feed --- plugins/OStatus/scripts/resub-feed.php | 74 ++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 plugins/OStatus/scripts/resub-feed.php diff --git a/plugins/OStatus/scripts/resub-feed.php b/plugins/OStatus/scripts/resub-feed.php new file mode 100644 index 0000000000..121d12109a --- /dev/null +++ b/plugins/OStatus/scripts/resub-feed.php @@ -0,0 +1,74 @@ +#!/usr/bin/env php +. + */ + +define('INSTALLDIR', realpath(dirname(__FILE__) . '/../../..')); + +$helptext = <<huburi with new subscription for $sub->uri\n"; +$ok = $sub->subscribe(); + +if ($ok) { + print "ok\n"; +} else { + print "Could not confirm.\n"; +} + +$sub2 = FeedSub::staticGet('topic', $feedurl); + +print "\n"; +print "New state:\n"; +showSub($sub2); + +function showSub($sub) +{ + print " Subscription state: $sub->sub_state\n"; + print " Verify token: $sub->verify_token\n"; + print " Signature secret: $sub->secret\n"; + print " Sub start date: $sub->sub_start\n"; + print " Record created: $sub->created\n"; + print " Record modified: $sub->modified\n"; +} From 7bdea95ccbf31cf9c9191a93c44dedb22f1fd3df Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Fri, 23 Apr 2010 06:55:46 -0700 Subject: [PATCH 06/14] Fix to make blowing of replies stream cache more consistent when receiving replies. (Was being done at mail notify time instead of at save time for local replies; now moved to reply save time internally so it can't get forgotten) --- classes/Notice.php | 4 +--- classes/Reply.php | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/classes/Notice.php b/classes/Notice.php index 4cf12fc6f9..c4a3168881 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -985,8 +985,6 @@ class Notice extends Memcached_DataObject $reply->profile_id = $user->id; $id = $reply->insert(); - - self::blow('reply:stream:%d', $user->id); } } @@ -1052,6 +1050,7 @@ class Notice extends Memcached_DataObject throw new ServerException("Couldn't save reply for {$this->id}, {$mentioned->id}"); } else { $replied[$mentioned->id] = 1; + self::blow('reply:stream:%d', $mentioned->id); } } } @@ -1107,7 +1106,6 @@ class Notice extends Memcached_DataObject foreach ($recipientIds as $recipientId) { $user = User::staticGet('id', $recipientId); if (!empty($user)) { - self::blow('reply:stream:%d', $recipientId); mail_notify_attn($user, $this); } } diff --git a/classes/Reply.php b/classes/Reply.php index 659e04c925..dc6296bda3 100644 --- a/classes/Reply.php +++ b/classes/Reply.php @@ -22,6 +22,20 @@ class Reply extends Memcached_DataObject /* the code above is auto generated do not remove the tag below */ ###END_AUTOCODE + /** + * Wrapper for record insertion to update related caches + */ + function insert() + { + $result = parent::insert(); + + if ($result) { + self::blow('reply:stream:%d', $this->profile_id); + } + + return $result; + } + function stream($user_id, $offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $max_id=0) { $ids = Notice::stream(array('Reply', '_streamDirect'), From 67b8b1334fc53fb06f1a751e534533e30b7cfd01 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Fri, 23 Apr 2010 07:10:36 -0700 Subject: [PATCH 07/14] Fix keys / keyTypes for Blacklist plugin - was spewing notices for undefined array indexes when saving blacklist entries from admin panel --- plugins/Blacklist/Homepage_blacklist.php | 4 ++-- plugins/Blacklist/Nickname_blacklist.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/Blacklist/Homepage_blacklist.php b/plugins/Blacklist/Homepage_blacklist.php index 32080667e1..ec89ee4bd8 100644 --- a/plugins/Blacklist/Homepage_blacklist.php +++ b/plugins/Blacklist/Homepage_blacklist.php @@ -94,7 +94,7 @@ class Homepage_blacklist extends Memcached_DataObject function keys() { - return array('pattern' => 'K'); + return array_keys($this->keyTypes()); } /** @@ -108,7 +108,7 @@ class Homepage_blacklist extends Memcached_DataObject function keyTypes() { - return $this->keys(); + return array('pattern' => 'K'); } /** diff --git a/plugins/Blacklist/Nickname_blacklist.php b/plugins/Blacklist/Nickname_blacklist.php index 9810631444..e8545292d1 100644 --- a/plugins/Blacklist/Nickname_blacklist.php +++ b/plugins/Blacklist/Nickname_blacklist.php @@ -88,7 +88,7 @@ class Nickname_blacklist extends Memcached_DataObject function keys() { - return array('pattern' => 'K'); + return array_keys($this->keyTypes()); } /** @@ -99,7 +99,7 @@ class Nickname_blacklist extends Memcached_DataObject function keyTypes() { - return $this->keys(); + return array('pattern' => 'K'); } /** From 390a2a8624b71be7d598b945452fc6e0000f3df5 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Fri, 23 Apr 2010 07:17:52 -0700 Subject: [PATCH 08/14] Fix for Blacklist plugin: was saving an empty entry if blacklist was empty, which would match *all* possible nickname registrations, preventing all registration on mozilla.status.net. Now saving only non-empty lines, and only matching non-empty lines so we don't fail if we still have a bogus entry. --- plugins/Blacklist/BlacklistPlugin.php | 4 ++-- plugins/Blacklist/blacklistadminpanel.php | 29 +++++++++++------------ 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/plugins/Blacklist/BlacklistPlugin.php b/plugins/Blacklist/BlacklistPlugin.php index adc4d9d7e2..63bffe2c6f 100644 --- a/plugins/Blacklist/BlacklistPlugin.php +++ b/plugins/Blacklist/BlacklistPlugin.php @@ -262,7 +262,7 @@ class BlacklistPlugin extends Plugin $patterns = $this->_getUrlPatterns(); foreach ($patterns as $pattern) { - if (preg_match("/$pattern/", $url)) { + if ($pattern != '' && preg_match("/$pattern/", $url)) { return false; } } @@ -285,7 +285,7 @@ class BlacklistPlugin extends Plugin $patterns = $this->_getNicknamePatterns(); foreach ($patterns as $pattern) { - if (preg_match("/$pattern/", $nickname)) { + if ($pattern != '' && preg_match("/$pattern/", $nickname)) { return false; } } diff --git a/plugins/Blacklist/blacklistadminpanel.php b/plugins/Blacklist/blacklistadminpanel.php index b996aba8dc..23c503cd82 100644 --- a/plugins/Blacklist/blacklistadminpanel.php +++ b/plugins/Blacklist/blacklistadminpanel.php @@ -88,28 +88,27 @@ class BlacklistadminpanelAction extends AdminPanelAction function saveSettings() { - $nickPatterns = array(); - - $rawNickPatterns = explode("\n", $this->trimmed('blacklist-nicknames')); - - foreach ($rawNickPatterns as $raw) { - $nickPatterns[] = trim($raw); - } - + $nickPatterns = $this->splitPatterns($this->trimmed('blacklist-nicknames')); Nickname_blacklist::saveNew($nickPatterns); - $rawUrlPatterns = explode("\n", $this->trimmed('blacklist-urls')); - $urlPatterns = array(); - - foreach ($rawUrlPatterns as $raw) { - $urlPatterns[] = trim($raw); - } - + $urlPatterns = $this->splitPatterns($this->trimmed('url-nicknames')); Homepage_blacklist::saveNew($urlPatterns); return; } + protected function splitPatterns($text) + { + $patterns = array(); + foreach (explode("\n", $text) as $raw) { + $trimmed = trim($raw); + if ($trimmed != '') { + $patterns[] = $trimmed; + } + } + return $patterns; + } + /** * Validate the values * From 0f975f42159ce714b59b5d7ca958f3f5ee1b226b Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Fri, 23 Apr 2010 08:24:53 -0700 Subject: [PATCH 09/14] Fix to regression in last commit; wrong field name for homepage blacklist --- plugins/Blacklist/blacklistadminpanel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/Blacklist/blacklistadminpanel.php b/plugins/Blacklist/blacklistadminpanel.php index 23c503cd82..4289dec1ba 100644 --- a/plugins/Blacklist/blacklistadminpanel.php +++ b/plugins/Blacklist/blacklistadminpanel.php @@ -91,7 +91,7 @@ class BlacklistadminpanelAction extends AdminPanelAction $nickPatterns = $this->splitPatterns($this->trimmed('blacklist-nicknames')); Nickname_blacklist::saveNew($nickPatterns); - $urlPatterns = $this->splitPatterns($this->trimmed('url-nicknames')); + $urlPatterns = $this->splitPatterns($this->trimmed('blacklist-urls')); Homepage_blacklist::saveNew($urlPatterns); return; From 4beaba9fb013ab32be0e07fe4d25a622c95b8a06 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Fri, 23 Apr 2010 11:28:50 -0700 Subject: [PATCH 10/14] Ticket #93: pretty up the auto-submit for OpenID logins a bit. * throwing in our spinner * cleanup of texts * "If this doesn't go through click the button" instead of just a mystery button * slightly faster submission: immediate at end of page rather than waiting for jQuery to confirm document setup completion --- plugins/OpenID/openid.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/plugins/OpenID/openid.php b/plugins/OpenID/openid.php index 1524389177..4ec336e1c3 100644 --- a/plugins/OpenID/openid.php +++ b/plugins/OpenID/openid.php @@ -299,11 +299,21 @@ class AutosubmitAction extends Action function title() { - return _m('OpenID Auto-Submit'); + return _m('OpenID Login Submission'); } function showContent() { + $this->raw('

'); + // @fixme this would be better using standard CSS class, but the present theme's a bit scary. + $this->element('img', array('src' => Theme::path('images/icons/icon_processing.gif', 'base'), + // for some reason the base CSS sets s as block display?! + 'style' => 'display: inline')); + $this->text(_m('Requesting authorization from your login provider...')); + $this->raw('

'); + $this->raw('

'); + $this->text(_m('If you are not redirected to your login provider in a few seconds, try pushing the button below.')); + $this->raw('

'); $this->raw($this->form_html); } @@ -311,8 +321,6 @@ class AutosubmitAction extends Action { parent::showScripts(); $this->element('script', null, - '$(document).ready(function() { ' . - ' $(\'#'. $this->form_id .'\').submit(); '. - '});'); + 'document.getElementById(\'' . $this->form_id . '\').submit();'); } } From 9c8052e755e5ad4c8120ace9acdd75ee910e2ab7 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Fri, 23 Apr 2010 12:54:31 -0700 Subject: [PATCH 11/14] Rerun feed discovery and update the feed, salmon, and hub for the given OStatus remote profile. Restarts subscription fresh as well. update-profile.php -sexample.com http://example.com/path/to/profile/url --- plugins/OStatus/scripts/update-profile.php | 147 +++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 plugins/OStatus/scripts/update-profile.php diff --git a/plugins/OStatus/scripts/update-profile.php b/plugins/OStatus/scripts/update-profile.php new file mode 100644 index 0000000000..d06de4f903 --- /dev/null +++ b/plugins/OStatus/scripts/update-profile.php @@ -0,0 +1,147 @@ +#!/usr/bin/env php +. + */ + +define('INSTALLDIR', realpath(dirname(__FILE__) . '/../../..')); + +$helptext = <<uri\n"; +showProfile($oprofile); + +print "\n"; +print "Re-running feed discovery for profile URL $oprofile->uri\n"; +// @fixme will bork where the URI isn't the profile URL for now +$discover = new FeedDiscovery(); +$feedurl = $discover->discoverFromURL($oprofile->uri); +$huburi = $discover->getAtomLink('hub'); +$salmonuri = $discover->getAtomLink(Salmon::NS_REPLIES); + +print " Feed URL: $feedurl\n"; +print " Hub URL: $huburi\n"; +print " Salmon URL: $salmonuri\n"; + +if ($feedurl != $oprofile->feeduri || $salmonuri != $oprofile->salmonuri) { + print "\n"; + print "Updating...\n"; + // @fixme update keys :P + #$orig = clone($oprofile); + #$oprofile->feeduri = $feedurl; + #$oprofile->salmonuri = $salmonuri; + #$ok = $oprofile->update($orig); + $ok = $oprofile->query('UPDATE ostatus_profile SET ' . + 'feeduri=\'' . $oprofile->escape($feedurl) . '\',' . + 'salmonuri=\'' . $oprofile->escape($salmonuri) . '\' ' . + 'WHERE uri=\'' . $oprofile->escape($uri) . '\''); + + if (!$ok) { + print "Failed to update profile record...\n"; + exit(1); + } + + $oprofile->decache(); +} else { + print "\n"; + print "Ok, ostatus_profile record unchanged.\n\n"; +} + +$sub = FeedSub::ensureFeed($feedurl); + +if ($huburi != $sub->huburi) { + print "\n"; + print "Updating hub record for feed; was $sub->huburi\n"; + $orig = clone($sub); + $sub->huburi = $huburi; + $ok = $sub->update($orig); + + if (!$ok) { + print "Failed to update sub record...\n"; + exit(1); + } +} else { + print "\n"; + print "Feed record ok, not changing.\n\n"; +} + +print "\n"; +print "Pinging hub $sub->huburi with new subscription for $sub->uri\n"; +$ok = $sub->subscribe(); + +if ($ok) { + print "ok\n"; +} else { + print "Could not confirm.\n"; +} + +$o2 = Ostatus_profile::staticGet('uri', $uri); + +print "\n"; +print "New profile state:\n"; +showProfile($o2); + +print "\n"; +print "New feed state:\n"; +$sub2 = FeedSub::ensureFeed($feedurl); +showSub($sub2); + +function showProfile($oprofile) +{ + print " Feed URL: $oprofile->feeduri\n"; + print " Salmon URL: $oprofile->salmonuri\n"; + print " Avatar URL: $oprofile->avatar\n"; + print " Profile ID: $oprofile->profile_id\n"; + print " Group ID: $oprofile->group_id\n"; + print " Record created: $oprofile->created\n"; + print " Record modified: $oprofile->modified\n"; +} + +function showSub($sub) +{ + print " Subscription state: $sub->sub_state\n"; + print " Verify token: $sub->verify_token\n"; + print " Signature secret: $sub->secret\n"; + print " Sub start date: $sub->sub_start\n"; + print " Record created: $sub->created\n"; + print " Record modified: $sub->modified\n"; +} From 8fd0059bf69ed16ed4efad7b8e16dc2afda32e18 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Fri, 23 Apr 2010 15:40:48 -0700 Subject: [PATCH 12/14] Test cases and fixes for Atom and RSS content decoding. Fix extraction of Atom and ; we were failing to escape plaintext source data to HTML, and doing an extraneous double-deescape on HTML source resulting in breakage of notices containing text that looks like HTML. Only was working correctly previously. Fixes for RSS2 content processing: we were failing to load at all due to using wrong element name, and were applying an extraneous de-escape for rather than the escaping that is required to turn plaintext into HTML. (Per spec, must be plaintext.) --- lib/activity.php | 14 +++++-- lib/activityutils.php | 12 +++++- tests/ActivityParseTests.php | 77 ++++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+), 5 deletions(-) diff --git a/lib/activity.php b/lib/activity.php index 5d6230c6df..27f09ab4d4 100644 --- a/lib/activity.php +++ b/lib/activity.php @@ -83,6 +83,7 @@ class Activity const CREATOR = 'creator'; const CONTENTNS = 'http://purl.org/rss/1.0/modules/content/'; + const ENCODED = 'encoded'; public $actor; // an ActivityObject public $verb; // a string (the URL) @@ -268,14 +269,21 @@ class Activity $this->title = ActivityUtils::childContent($item, ActivityObject::TITLE, self::RSS); - $contentEl = ActivityUtils::child($item, ActivityUtils::CONTENT, self::CONTENTNS); + $contentEl = ActivityUtils::child($item, self::ENCODED, self::CONTENTNS); if (!empty($contentEl)) { - $this->content = htmlspecialchars_decode($contentEl->textContent, ENT_QUOTES); + // XML node's text content is HTML; no further processing needed. + $this->content = $contentEl->textContent; } else { $descriptionEl = ActivityUtils::child($item, self::DESCRIPTION, self::RSS); if (!empty($descriptionEl)) { - $this->content = htmlspecialchars_decode($descriptionEl->textContent, ENT_QUOTES); + // Per spec, must be plaintext. + // In practice, often there's HTML... but these days good + // feeds are using which is explicitly + // real HTML. + // We'll treat this following spec, and do HTML escaping + // to convert from plaintext to HTML. + $this->content = htmlspecialchars($descriptionEl->textContent); } } diff --git a/lib/activityutils.php b/lib/activityutils.php index a7e99fb11e..401fd7fc28 100644 --- a/lib/activityutils.php +++ b/lib/activityutils.php @@ -213,11 +213,19 @@ class ActivityUtils // slavishly following http://atompub.org/rfc4287.html#rfc.section.4.1.3.3 if (empty($type) || $type == 'text') { - return $el->textContent; + // We have plaintext saved as the XML text content. + // Since we want HTML, we need to escape any special chars. + return htmlspecialchars($el->textContent); } else if ($type == 'html') { + // We have HTML saved as the XML text content. + // No additional processing required once we've got it. $text = $el->textContent; - return htmlspecialchars_decode($text, ENT_QUOTES); + return $text; } else if ($type == 'xhtml') { + // Per spec, the contains a single + // HTML
with XHTML namespace on it as a child node. + // We need to pull all of that
's child nodes and + // serialize them back to an (X)HTML source fragment. $divEl = ActivityUtils::child($el, 'div', 'http://www.w3.org/1999/xhtml'); if (empty($divEl)) { return null; diff --git a/tests/ActivityParseTests.php b/tests/ActivityParseTests.php index 4563da9146..378478d741 100644 --- a/tests/ActivityParseTests.php +++ b/tests/ActivityParseTests.php @@ -32,6 +32,18 @@ class ActivityParseTests extends PHPUnit_Framework_TestCase $this->assertEquals('tag:versioncentral.example.org,2009:/change/1643245', $act->objects[0]->id); } + public function testExample2() + { + global $_example2; + $dom = DOMDocument::loadXML($_example2); + $act = new Activity($dom->documentElement); + + $this->assertFalse(empty($act)); + // Did we handle correctly with a typical payload? + $this->assertEquals("

Geraldine posted a Photo on PhotoPanic

\n " . + "", trim($act->content)); + } + public function testExample3() { global $_example3; @@ -305,6 +317,71 @@ class ActivityParseTests extends PHPUnit_Framework_TestCase } + public function testAtomContent() + { + $tests = array(array("Some regular plain text.", + "Some regular plain text."), + array("<b>this is not HTML</b>", + "<b>this is not HTML</b>"), + array("Some regular plain HTML.", + "Some regular plain HTML."), + array("<b>this is too HTML</b>", + "this is too HTML"), + array("&lt;b&gt;but this is not HTML!&lt;/b&gt;", + "<b>but this is not HTML!</b>"), + array("
Some regular plain XHTML.
", + "Some regular plain XHTML."), + array("
This is some XHTML!
", + "This is some XHTML!"), + array("
<b>This is not some XHTML!</b>
", + "<b>This is not some XHTML!</b>"), + array("
&lt;b&gt;This is not some XHTML either!&lt;/b&gt;
", + "&lt;b&gt;This is not some XHTML either!&lt;/b&gt;")); + foreach ($tests as $data) { + list($source, $output) = $data; + $xml = "" . + "http://example.com/fakeid" . + "Test" . + "Atom content tests" . + $source . + ""; + $dom = DOMDocument::loadXML($xml); + $act = new Activity($dom->documentElement); + + $this->assertFalse(empty($act)); + $this->assertEquals($output, trim($act->content)); + } + } + + public function testRssContent() + { + $tests = array(array("Some regular plain HTML.", + "Some regular plain HTML."), + array("Some <b>exciting bold HTML</b>", + "Some exciting bold HTML"), + array("Some &lt;b&gt;escaped non-HTML.&lt;/b&gt;", + "Some <b>escaped non-HTML.</b>"), + array("Some plain text.", + "Some plain text."), + array("Some <b>non-HTML text</b>", + "Some <b>non-HTML text</b>"), + array("Some &lt;b&gt;double-escaped text&lt;/b&gt;", + "Some &lt;b&gt;double-escaped text&lt;/b&gt;")); + foreach ($tests as $data) { + list($source, $output) = $data; + $xml = "" . + "http://example.com/fakeid" . + "RSS content tests" . + $source . + ""; + $dom = DOMDocument::loadXML($xml); + $act = new Activity($dom->documentElement); + + $this->assertFalse(empty($act)); + $this->assertEquals($output, trim($act->content)); + } + } + } $_example1 = << Date: Wed, 28 Apr 2010 11:05:31 -0700 Subject: [PATCH 13/14] add rsd to the list of login actions Allows rsd.xml to be reached on private sites. Fixes http://status.net/trac/ticket/2309 Conflicts: index.php --- index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.php b/index.php index ea5c802779..3778ffe420 100644 --- a/index.php +++ b/index.php @@ -185,7 +185,7 @@ function checkMirror($action_obj, $args) function isLoginAction($action) { - static $loginActions = array('login', 'recoverpassword', 'api', 'doc', 'register', 'publicxrds', 'otp'); + static $loginActions = array('login', 'recoverpassword', 'api', 'doc', 'register', 'publicxrds', 'otp', 'rsd'); $login = null; From cb5d6d5c30ab6235283005530fadd0d185b38499 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Wed, 28 Apr 2010 23:06:08 +0000 Subject: [PATCH 14/14] Fix charset setting for plugin localizations; default setting was blanking out non-ASCII chars. Needed for eg Bulgarian translation of Facebook plugin, was previously showing all as ???s. Now works yay! --- lib/plugin.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/plugin.php b/lib/plugin.php index 65ccdafbb0..f63bdf3093 100644 --- a/lib/plugin.php +++ b/lib/plugin.php @@ -91,6 +91,7 @@ class Plugin $path = INSTALLDIR . "/plugins/$name/locale"; if (file_exists($path) && is_dir($path)) { bindtextdomain($name, $path); + bind_textdomain_codeset($name, 'UTF-8'); } } }