summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README182
-rw-r--r--actions/newnotice.php8
-rw-r--r--actions/profilesettings.php30
-rw-r--r--classes/Memcached_DataObject.php5
-rw-r--r--classes/statusnet.ini21
-rw-r--r--lib/common.php4
-rw-r--r--lib/mail.php4
-rw-r--r--plugins/GeonamesPlugin.php211
8 files changed, 270 insertions, 195 deletions
diff --git a/README b/README
index dc2e2b4ba..6e39890cb 100644
--- a/README
+++ b/README
@@ -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;
}
/**