diff options
-rw-r--r-- | README | 182 | ||||
-rw-r--r-- | actions/newnotice.php | 8 | ||||
-rw-r--r-- | actions/profilesettings.php | 30 | ||||
-rw-r--r-- | classes/Memcached_DataObject.php | 5 | ||||
-rw-r--r-- | classes/statusnet.ini | 21 | ||||
-rw-r--r-- | lib/common.php | 4 | ||||
-rw-r--r-- | lib/mail.php | 4 | ||||
-rw-r--r-- | plugins/GeonamesPlugin.php | 211 |
8 files changed, 270 insertions, 195 deletions
@@ -2,8 +2,8 @@ README ------ -StatusNet 0.8.2 ("Life and How to Live It") -1 Nov 2009 +StatusNet 0.9.0 ("Stand") Release Candidate 2 +22 Dec 2009 This is the README file for StatusNet (formerly Laconica), the Open Source microblogging platform. It includes installation instructions, @@ -16,10 +16,10 @@ About StatusNet (formerly Laconica) is a Free and Open Source microblogging platform. It helps people in a community, company or group to exchange -short (140 character) messages over the Web. Users can choose which -people to "follow" and receive only their friends' or colleagues' -status messages. It provides a similar service to sites like Twitter, -Jaiku, Yammer, and Plurk. +short (140 characters, by default) messages over the Web. Users can +choose which people to "follow" and receive only their friends' or +colleagues' status messages. It provides a similar service to sites +like Twitter, Jaiku, Yammer, and Plurk. With a little work, status messages can be sent to mobile phones, instant messenger programs (GTalk/Jabber), and specially-designed @@ -77,81 +77,96 @@ for additional terms. New this version ================ -This is a minor feature and bugfix release since version 0.8.1, -released Aug 26 2009. Notable changes this version: - -- New script for deleting user accounts. Not particularly safe or - community-friendly. Better for deleting abusive accounts than for - users who are 'retiring'. -- Improved detection of URLs in notices, specifically for punctuation - chars like ~, :, $, _, -, +, !, @, and %. -- Removed some extra <dl> semantic HTML code. -- Correct error in status-network database ini file (having multiple - statusnet sites with a single codebase) -- Fixed error output for Twitter posting failures. -- Fixed bug in Twitter queue handler that requeued inapplicable - notices ad infinitum. -- Improve FOAF output for remote users. -- new commands to join and leave groups. -- Fixed bug in which you cannot turn off importing friends timelines - flag. -- Better error handling in Twitter posting. -- Show oEmbed data for XHTML files as well as plain HTML. -- Updated bug database link in README. -- add support for HTTP Basic Auth in PHP CGI or FastCGI (e.g. GoDaddy). -- autofocus input to selected entry elements depending on page. -- updated layout for filter-by-tag form. -- better layout for inbox and outbox pages. -- fix highlighting search terms in attributes of notice list elements. -- Correctly handle errors in linkback plugin. -- Updated biz theme. -- Updated cloudy theme. -- Don't match '::' as an IPv6 address. -- Use the same decision logic for deciding whether to mark an - attachment as an enclosure in RSS or as a paperclip item in Web - output. -- Fixed a bug in the Piwik plugin that hard-coded the site ID. -- Add a param, inreplyto, to notice/new to allow an explicit response - to another notice. -- Show username in subject of emails. -- Check if avatar exists before trying to delete it. -- Correctly add omb_version to response for request token in OMB. -- Add a few more SMS carriers. -- Add a few more notice sources. -- Vary: header. -- Improvements to the AutoCompletePlugin. -- Check for 'dl' before using it. -- Make it impossible to delete self-subscriptions via the API. -- Fix pagination of tagged user pages. -- Make PiwikAnalyticsPlugin work with addPlugin(). -- Removed trailing single space in user nicknames in notice lists. -- Show context link if a notice starts a conversation. -- blacklist all files and directories in install dir. -- handle GoDaddy-style PATH_INFO, including script name. -- add home_timeline synonym for friends_timeline. -- Add a popup window for the realtime plugin. -- Add some more streams for the realtime plugin. -- Fix a bug that overwrote group creation timestamp on every edit. -- Moved HTTP error code strings to a class variable. -- The Twitter API now returns server errors in the correct format. -- Reset the doctype for HTML output. -- Fixed a number of notices. -- Don't show search suggestions for private sites. -- Some corrections to FBConnect nav overrides. -- Slightly less database-intensive session management. -- Updated name of software in installer script. -- Include long-form attachment URLs if url-shortener is disabled. -- Include updated localisations for Polish, Greek, Hebrew, Icelandic, - Norwegian, and Chinese. -- Include upstream fixes to gettext.php. -- Correct for regression in Facebook API for updates. -- Ignore "Sent from my iPhone" (and similar) in mail updates. -- Use the NICKNAME_FMT constant for detecting nicknames. -- Check for site servername config'd. -- Compatibility fix for empty status updates with Twitter API. -- Option to show files privately (EXPERIMENTAL! Use with caution.) -- a script to register a new user. -- a script to make a user admin of a group. +This is a major feature release since version 0.8.2, released Nov 1 2009. +Notable changes this version: + +- Records of deleted notices are stored without the notice content. +- Much of the optional core featureset has been moved to plugins. +- OpenID support moved from core to a plugin. Helps test the strength of + our plugin architecture and makes it easy to disable this + functionality for e.g. intranet sites. +- Many additional hook events (see EVENTS.txt for details). +- OMB 0.1 support re-implemented using libomb. +- Re-structure database so notices, messages, bios and group + descriptions can be over 140 characters. Limit defined by + site administrator as configuration option; can be unlimited. +- Configuration data now optionally stored in the database, which + overrides any settings in config files. +- Twitter integration re-implemented as a plugin. +- Facebook integration re-implemented as a plugin. +- Role-based authorization framework. Users can have named roles, and + roles can have rights (e.g., to delete notices, change configuration + data, or ban uncooperative users). Default roles 'admin' (for + configuration) and 'moderator' (for community management) added. +- Plugin for PubSubHubBub (PuSH) support. +- Considerable code style cleanup to meet PEAR code standards. +- Made a common library for HTTP-client access which uses available + HTTP libraries where possible. +- Added statuses/home_timeline method to API. +- Hooks for plugins to handle notices offline, either by defining + their own queue handler scripts or to use a default plugin queue + handler script. +- Plugins can now modify the database schema, adding their own tables + or modifying existing ones. +- Groups API. +- Twitter API supports Web caching for some methods. +- Twitter API refactored into one-action-per-method. +- Realtime plugin supports a tear-off window. +- FOAF for groups. +- Moved all JavaScript tags to just before </body> by default, + significantly speeding up apparent page load time. +- Added a Realtime plugin for Orbited server. +- Added a mobile plugin to give a more mobile-phone-friendly layout + when a mobile browser is detected. +- Use CSS sprites for most common icons. +- Fixes for images and buttons on Web output. +- New plugin requires that users validate their email before posting. +- New plugin UserFlag lets users flag other profiles for review. +- Considerably better i18n support. Use TranslateWiki to update + translations. +- Notices and profiles now store location information. +- New plugin, Geonames, for turning location names and lat/long pairs + into structured IDs and vice versa. Architecture reusable for other + systems. +- Better check of license compatibility between site licenses. +- Some improvements in XMPP output. +- Media upload in the API. +- Replies appear in the user's inbox. +- Improved the UI on the bookmarklet. +- StatusNet identities can be used as OpenID identities. +- Script to register a user. +- Script to make someone a group admin. +- Script to make someone a site admin or moderator. +- 'login' command. +- Pluggable authentication. +- LDAP authentication plugin. +- Script for console interaction with the site (!). +- Users don't see group posts from people they've blocked. +- Admin panel interface for changing site configuration. +- Users can be sandboxed (limited contributions) or silenced + (no contributions) by moderators. +- Many changes to make language usage more consistent. +- Sphinx search moved to a plugin. +- GeoURL plugin. +- Profile and group lists support hAtom. +- Massive refactoring of util.js. +- Mapstraction plugin to show maps on inbox and profile pages. +- Play/pause buttons for realtime notices. +- Support for geo microformat. +- Partial support for feed subscriptions, RSSCloud, PubSubHubBub. +- Support for geolocation in browser (Chrome, Firefox). +- Quit trying to negotiate HTML format. Always use text/html. + We lose, and so do Web standards. Boo. +- Better logging of request info. +- Better output for errors in Web interface. +- No longer store .mo files; these need to be generated. +- Minify plugin. +- Events to allow pluginizing logger. +- New framework for plugin localization. +- Gravatar plugin. +- Add support for "repeats" (similar to Twitter's "retweets"). +- Support for repeats in Twitter API. +- Better notification of direct messages. Prerequisites ============= @@ -697,13 +712,9 @@ to users on a remote site. (Or not... it's not well tested.) The If fancy URLs is enabled, access to file attachments can also be restricted to logged-in users only. Uncomment the appropriate rewrite -<<<<<<< HEAD:README rule in .htaccess or your server's httpd.conf. (This most likely will not work if you are using a virtual server for attachments, so consider the performance/security tradeoff.) -======= -rule in .htaccess or your server's httpd.conf. ->>>>>>> 446de62... Revert "Added some explanatory text to README":README Upgrading ========= @@ -1600,6 +1611,7 @@ if anyone's been overlooked in error. * Federico Marani * Craig Andrews * mEDI +* Brett Taylor Thanks also to the developers of our upstream library code and to the thousands of people who have tried out Identi.ca, installed StatusNet, diff --git a/actions/newnotice.php b/actions/newnotice.php index c6c70e326..c014f1781 100644 --- a/actions/newnotice.php +++ b/actions/newnotice.php @@ -169,6 +169,14 @@ class NewnoticeAction extends Action $location_id = $this->trimmed('location_id'); $location_ns = $this->trimmed('location_ns'); + if (!empty($lat) && !empty($lon) && empty($location_id)) { + $location = Location::fromLatLon($lat, $lon); + if (!empty($location)) { + $location_id = $location->location_id; + $location_ns = $location->location_ns; + } + } + $upload = null; $upload = MediaFile::fromUpload('attach'); diff --git a/actions/profilesettings.php b/actions/profilesettings.php index 359664096..acfcbcd00 100644 --- a/actions/profilesettings.php +++ b/actions/profilesettings.php @@ -69,7 +69,7 @@ class ProfilesettingsAction extends AccountSettingsAction function getInstructions() { return _('You can update your personal profile info here '. - 'so people know more about you.'); + 'so people know more about you.'); } function showScripts() @@ -92,9 +92,9 @@ class ProfilesettingsAction extends AccountSettingsAction $profile = $user->getProfile(); $this->elementStart('form', array('method' => 'post', - 'id' => 'form_settings_profile', - 'class' => 'form_settings', - 'action' => common_local_url('profilesettings'))); + 'id' => 'form_settings_profile', + 'class' => 'form_settings', + 'action' => common_local_url('profilesettings'))); $this->elementStart('fieldset'); $this->element('legend', null, _('Profile information')); $this->hidden('token', common_session_token()); @@ -185,7 +185,7 @@ class ProfilesettingsAction extends AccountSettingsAction $token = $this->trimmed('token'); if (!$token || $token != common_session_token()) { $this->showForm(_('There was a problem with your session token. '. - 'Try again, please.')); + 'Try again, please.')); return; } @@ -203,15 +203,15 @@ class ProfilesettingsAction extends AccountSettingsAction // Some validation if (!Validate::string($nickname, array('min_length' => 1, - 'max_length' => 64, - 'format' => NICKNAME_FMT))) { + 'max_length' => 64, + 'format' => NICKNAME_FMT))) { $this->showForm(_('Nickname must have only lowercase letters and numbers and no spaces.')); return; } else if (!User::allowed_nickname($nickname)) { $this->showForm(_('Not a valid nickname.')); return; } else if (!is_null($homepage) && (strlen($homepage) > 0) && - !Validate::uri($homepage, array('allowed_schemes' => array('http', 'https')))) { + !Validate::uri($homepage, array('allowed_schemes' => array('http', 'https')))) { $this->showForm(_('Homepage is not a valid URL.')); return; } else if (!is_null($fullname) && mb_strlen($fullname) > 255) { @@ -253,15 +253,15 @@ class ProfilesettingsAction extends AccountSettingsAction $user->query('BEGIN'); if ($user->nickname != $nickname || - $user->language != $language || - $user->timezone != $timezone) { + $user->language != $language || + $user->timezone != $timezone) { common_debug('Updating user nickname from ' . $user->nickname . ' to ' . $nickname, - __FILE__); + __FILE__); common_debug('Updating user language from ' . $user->language . ' to ' . $language, - __FILE__); + __FILE__); common_debug('Updating user timezone from ' . $user->timezone . ' to ' . $timezone, - __FILE__); + __FILE__); $original = clone($user); @@ -281,7 +281,7 @@ class ProfilesettingsAction extends AccountSettingsAction } } -// XXX: XOR + // XXX: XOR if ($user->autosubscribe ^ $autosubscribe) { $original = clone($user); @@ -351,7 +351,7 @@ class ProfilesettingsAction extends AccountSettingsAction $user = common_current_user(); $other = User::staticGet('nickname', $nickname); if (!$other) { - return false; + return false; } else { return $other->id != $user->id; } diff --git a/classes/Memcached_DataObject.php b/classes/Memcached_DataObject.php index af8e24090..be8137573 100644 --- a/classes/Memcached_DataObject.php +++ b/classes/Memcached_DataObject.php @@ -123,6 +123,11 @@ class Memcached_DataObject extends DB_DataObject } static function cacheKey($cls, $k, $v) { + if (is_object($cls) || is_object($j) || is_object($v)) { + $e = new Exception(); + common_log(LOG_ERR, __METHOD__ . ' object in param: ' . + str_replace("\n", " ", $e->getTraceAsString())); + } return common_cache_key(strtolower($cls).':'.$k.':'.$v); } diff --git a/classes/statusnet.ini b/classes/statusnet.ini index ff4ef2c14..2cc37dbfe 100644 --- a/classes/statusnet.ini +++ b/classes/statusnet.ini @@ -544,3 +544,24 @@ modified = 384 [user_group__keys] id = N + +[user_openid] +canonical = 130 +display = 130 +user_id = 129 +created = 142 +modified = 384 + +[user_openid__keys] +canonical = K +display = U + +[user_openid_trustroot] +trustroot = 130 +user_id = 129 +created = 142 +modified = 384 + +[user_openid__keys] +trustroot = K +user_id = K
\ No newline at end of file diff --git a/lib/common.php b/lib/common.php index 732c22bfd..7fa1910af 100644 --- a/lib/common.php +++ b/lib/common.php @@ -20,9 +20,9 @@ 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; } +if (isset($_REQUEST['p']) && $_REQUEST['p'] == 'check-fancy') { exit; } -define('STATUSNET_VERSION', '0.9.0dev'); +define('STATUSNET_VERSION', '0.9.0rc2'); define('LACONICA_VERSION', STATUSNET_VERSION); // compatibility define('STATUSNET_CODENAME', 'Stand'); diff --git a/lib/mail.php b/lib/mail.php index dffac3262..472a88e06 100644 --- a/lib/mail.php +++ b/lib/mail.php @@ -599,6 +599,10 @@ function mail_notify_attn($user, $notice) $sender = $notice->getProfile(); + if ($sender->id == $user->id) { + return; + } + if (!$sender->hasRight(Right::EMAILONREPLY)) { return; } diff --git a/plugins/GeonamesPlugin.php b/plugins/GeonamesPlugin.php index a750f1242..0d12c1cf7 100644 --- a/plugins/GeonamesPlugin.php +++ b/plugins/GeonamesPlugin.php @@ -86,30 +86,36 @@ class GeonamesPlugin extends Plugin 'lang' => $language, 'type' => 'json'))); - if ($result->isOk()) { - $rj = json_decode($result->getBody()); - if (count($rj->geonames) > 0) { - $n = $rj->geonames[0]; + if (!$result->isOk()) { + $this->log(LOG_WARNING, "Error code " . $result->code . + " from " . $this->host . " for $name"); + return true; + } - $location = new Location(); + $rj = json_decode($result->getBody()); - $location->lat = $n->lat; - $location->lon = $n->lng; - $location->names[$language] = $n->name; - $location->location_id = $n->geonameId; - $location->location_ns = self::LOCATION_NS; + if (count($rj->geonames) <= 0) { + $this->log(LOG_WARNING, "No results in response from " . + $this->host . " for $name"); + return true; + } - $this->setCache(array('name' => $name, - 'language' => $language), - $location); + $n = $rj->geonames[0]; - // handled, don't continue processing! - return false; - } - } + $location = new Location(); + + $location->lat = $n->lat; + $location->lon = $n->lng; + $location->names[$language] = $n->name; + $location->location_id = $n->geonameId; + $location->location_ns = self::LOCATION_NS; + + $this->setCache(array('name' => $name, + 'language' => $language), + $location); - // Continue processing; we don't have the answer - return true; + // handled, don't continue processing! + return false; } /** @@ -143,38 +149,46 @@ class GeonamesPlugin extends Plugin array('geonameId' => $id, 'lang' => $language))); - if ($result->isOk()) { + if (!$result->isOk()) { + $this->log(LOG_WARNING, + "Error code " . $result->code . + " from " . $this->host . " for ID $id"); + return false; + } - $rj = json_decode($result->getBody()); + $rj = json_decode($result->getBody()); - if (count($rj->geonames) > 0) { + if (count($rj->geonames) <= 0) { + $this->log(LOG_WARNING, + "No results in response from " . + $this->host . " for ID $id"); + return false; + } - $parts = array(); + $parts = array(); - foreach ($rj->geonames as $level) { - if (in_array($level->fcode, array('PCLI', 'ADM1', 'PPL'))) { - $parts[] = $level->name; - } - } + foreach ($rj->geonames as $level) { + if (in_array($level->fcode, array('PCLI', 'ADM1', 'PPL'))) { + $parts[] = $level->name; + } + } - $last = $rj->geonames[count($rj->geonames)-1]; + $last = $rj->geonames[count($rj->geonames)-1]; - if (!in_array($level->fcode, array('PCLI', 'ADM1', 'PPL'))) { - $parts[] = $last->name; - } + if (!in_array($level->fcode, array('PCLI', 'ADM1', 'PPL'))) { + $parts[] = $last->name; + } - $location = new Location(); + $location = new Location(); - $location->location_id = $last->geonameId; - $location->location_ns = self::LOCATION_NS; - $location->lat = $last->lat; - $location->lon = $last->lng; - $location->names[$language] = implode(', ', array_reverse($parts)); + $location->location_id = $last->geonameId; + $location->location_ns = self::LOCATION_NS; + $location->lat = $last->lat; + $location->lon = $last->lng; + $location->names[$language] = implode(', ', array_reverse($parts)); - $this->setCache(array('id' => $last->geonameId), - $location); - } - } + $this->setCache(array('id' => $last->geonameId), + $location); // We're responsible for this NAMESPACE; nobody else // can resolve it @@ -217,48 +231,52 @@ class GeonamesPlugin extends Plugin 'lng' => $lon, 'lang' => $language))); - if ($result->isOk()) { - - $rj = json_decode($result->getBody()); - - if (count($rj->geonames) > 0) { + if (!$result->isOk()) { + $this->log(LOG_WARNING, + "Error code " . $result->code . + " from " . $this->host . " for coords $lat, $lon"); + return true; + } - $n = $rj->geonames[0]; + $rj = json_decode($result->getBody()); - $parts = array(); + if (count($rj->geonames) <= 0) { + $this->log(LOG_WARNING, + "No results in response from " . + $this->host . " for coords $lat, $lon"); + return true; + } - $location = new Location(); + $n = $rj->geonames[0]; - $parts[] = $n->name; + $parts = array(); - if (!empty($n->adminName1)) { - $parts[] = $n->adminName1; - } + $location = new Location(); - if (!empty($n->countryName)) { - $parts[] = $n->countryName; - } + $parts[] = $n->name; - $location->location_id = $n->geonameId; - $location->location_ns = self::LOCATION_NS; - $location->lat = $lat; - $location->lon = $lon; + if (!empty($n->adminName1)) { + $parts[] = $n->adminName1; + } - $location->names[$language] = implode(', ', $parts); + if (!empty($n->countryName)) { + $parts[] = $n->countryName; + } - $this->setCache(array('lat' => $lat, - 'lon' => $lon), - $location); + $location->location_id = $n->geonameId; + $location->location_ns = self::LOCATION_NS; + $location->lat = $lat; + $location->lon = $lon; - // Success! We handled it, so no further processing + $location->names[$language] = implode(', ', $parts); - return false; - } - } + $this->setCache(array('lat' => $lat, + 'lon' => $lon), + $location); - // For some reason we don't know, so pass. + // Success! We handled it, so no further processing - return true; + return false; } /** @@ -295,37 +313,44 @@ class GeonamesPlugin extends Plugin array('geonameId' => $location->location_id, 'lang' => $language))); - if ($result->isOk()) { + if (!$result->isOk()) { + $this->log(LOG_WARNING, + "Error code " . $result->code . + " from " . $this->host . " for ID " . $location->location_id); + return false; + } - $rj = json_decode($result->getBody()); + $rj = json_decode($result->getBody()); - if (count($rj->geonames) > 0) { + if (count($rj->geonames) <= 0) { + $this->log(LOG_WARNING, + "No results " . + " from " . $this->host . " for ID " . $location->location_id); + return false; + } - $parts = array(); + $parts = array(); - foreach ($rj->geonames as $level) { - if (in_array($level->fcode, array('PCLI', 'ADM1', 'PPL'))) { - $parts[] = $level->name; - } - } + foreach ($rj->geonames as $level) { + if (in_array($level->fcode, array('PCLI', 'ADM1', 'PPL'))) { + $parts[] = $level->name; + } + } - $last = $rj->geonames[count($rj->geonames)-1]; + $last = $rj->geonames[count($rj->geonames)-1]; - if (!in_array($level->fcode, array('PCLI', 'ADM1', 'PPL'))) { - $parts[] = $last->name; - } + if (!in_array($level->fcode, array('PCLI', 'ADM1', 'PPL'))) { + $parts[] = $last->name; + } - if (count($parts)) { - $name = implode(', ', array_reverse($parts)); - $this->setCache(array('id' => $location->location_id, - 'language' => $language), - $name); - return false; - } - } + if (count($parts)) { + $name = implode(', ', array_reverse($parts)); + $this->setCache(array('id' => $location->location_id, + 'language' => $language), + $name); } - return true; + return false; } /** |