summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README262
-rw-r--r--actions/sitenoticeadminpanel.php2
-rw-r--r--db/08to09.sql45
-rw-r--r--install.php189
-rw-r--r--lib/activity.php32
-rw-r--r--lib/adminpanelaction.php10
-rw-r--r--lib/apiaction.php2
-rw-r--r--lib/default.php1
-rw-r--r--plugins/OStatus/OStatusPlugin.php13
-rw-r--r--plugins/OStatus/actions/ostatusinit.php2
-rw-r--r--plugins/PubSubHubBub/PubSubHubBubPlugin.php285
-rw-r--r--plugins/PubSubHubBub/publisher.php86
-rwxr-xr-xscripts/setup_status_network.sh2
-rw-r--r--theme/base/css/display.css61
14 files changed, 307 insertions, 685 deletions
diff --git a/README b/README
index 75336eb83..caa4a2acd 100644
--- a/README
+++ b/README
@@ -2,8 +2,8 @@
README
------
-StatusNet 0.9.0 ("Stand") Beta 5
-1 Feb 2010
+StatusNet 0.9.0 ("Stand")
+4 Mar 2010
This is the README file for StatusNet (formerly Laconica), the Open
Source microblogging platform. It includes installation instructions,
@@ -14,21 +14,21 @@ for administrators. Information on using StatusNet can be found in the
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 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.
+StatusNet is a Free and Open Source microblogging platform. It helps
+people in a community, company or group to exchange 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,
+Google Buzz, or Yammer.
With a little work, status messages can be sent to mobile phones,
instant messenger programs (GTalk/Jabber), and specially-designed
desktop clients that support the Twitter API.
-StatusNet supports an open standard called OpenMicroBlogging
-<http://openmicroblogging.org/> that lets users on different Web sites
-or in different companies subscribe to each others' notices. It
-enables a distributed social network spread all across the Web.
+StatusNet supports an open standard called OStatus
+<http://ostatus.org/> that lets users in different networks follow
+each other. It enables a distributed social network spread all across
+the Web.
StatusNet was originally developed for the Open Software Service,
Identi.ca <http://identi.ca/>. It is shared with you in hope that you
@@ -77,203 +77,51 @@ for additional terms.
New this version
================
-This is a major feature release since version 0.8.2, released Nov 1 2009.
-It is also a security release since 0.9.0beta4 January 27 2010. Beta
-users are strongly encouraged to upgrade to deal with a security alert.
-
-http://status.net/wiki/Security_alert_0000002
+This is a major feature release since version 0.8.3, released Feb 1
+2010. It is the final release version of 0.9.0.
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.
-- New plugin to add "powered by StatusNet" to logo.
-- Returnto works for private sites.
-- Localisation updates, including new Persian translation.
-- CAS authentication plugin
-- Get rid of DB_DataObject native cache (big memory leaker)
-- setconfig.php script to set configuration variables
-- Blacklist plugin, to blacklist URLs and nicknames
-- Users can set flag whether they want to share location
- both in notice form (for one notice) and profile settings
- (any notice)
-- notice inboxes moved from normalized notice_inbox table to
- denormalized inbox table
-- Automatic compression of Memcache
-- Memory caching pluginized
-- Memcache, XCache, APC and Diskcache plugins
-- A script to update user locations
-- cache empty query results
-- A sample plugin to show best plugin practices
-- CacheLog plugin to debug cache accesses
-- Require users to login to view attachments on private sites
-- Plugin to use Mollom spam detection service
-- Plugin for RSSCloud
-- Add an array of default plugins
-- A version action to give credit to contributors and plugin
- developers
-- Daemon to read IMAP mailbox instead of using a mailbox script
-- Pass session information between SSL and non-SSL server
- when SSL set to 'sometimes'
-- Major refactoring of queue handlers to manage very
- large hosting site (like status.net)
-- SubscriptionThrottle plugin to prevent subscription spamming
-- Don't enqueue into plugin or SMS queues when disabled (breaks unqueuehandler if SMS queue isn't attached)
-- Improve name validation checks on local File references
-- fix local file include vulnerability in doc.php
-- Reusing fixed selector name for 'processing' in util.js
-- Removed hAtom pattern from registration page.
-- restructuring of User::registerNew() lost password munging
-- Add a script to clear the cache for a given key
-- buggy fetch for site owner
-- Added missing concat of </li> in Realtime response
-- Updated XHR binded events to work better in jQuery 1.4.1. Using .live() for event delegation instead of jQuery.data() and checking to see if an element was previously binded.
-- Updated jQuery Form Plugin from v2.17 to v2.36
-- Updated jQuery JavaScript Library from v1.3.2 to v1.4.1
-- move schema.type.php to typeschema.php like other files
-- Add Really Simple Discovery (RSD) support
-- Add a robots.txt URL to the site root
-- error clearing tags for profiles from memcached
-- on exceptions, stomp logs the error and reenqueues
-- add lat, lon, location and remove closing tag from geocode.php
-- Use passed-in lat long in geocode.php
-- better handling of null responses from geonames.org
-- Globalized form notice data geo values
-- Using jQuery chaining in FormNoticeXHR
-- Using form object instead of form_id and find(). Slightly faster and easier to read.
-- removed describeTable from base class, and fixed it up in pgsql
-- getTableDef() mostly working in postgres
-- move the schema DDL sql off into seperate files for each db we support
-- plugin to limit number of registered users
-- add hooks for user registration
-- live fast, die young in bash scripts
-- for single-user mode, retrieve either site owner or defined nickname
-- method to get the site owner
-- define a constant for the 'owner' role of a site
-- add simple cache getter/setter static functions to Memcached_DataObject
-- Adds notice author's name to @title in Realtime response
-- Hides .author from XHR response in showstream
-- Hides .author from XHR response in showstream
-- Fix more fatal errors in queue edge cases
-- Don't attempt to resend XMPP messages that can't be broadcast due to the profile being deleted.
-- Wrap each bit of distrib queue handler's saving operation in a try/catch; log exceptions but let everything else continue.
-- Log exceptions from queuedaemon.php if they're not already caught
-- Move sessions settings to its own panel
-- Fixes for status_network db object .ini and tag setter script
-- Add a script to set tags for sites
-- Adjust API authentication to also check for OAuth protocol params in the HTTP Authorization header, as defined in OAuth HTTP Authorization Scheme.
-- Last-chance distribution if enqueueing fails
-- Manual failover for stomp queues.
-- lost config in index.php made all traffic go to master
-- "Revert "move RW setup above user get in index.php so remember_me works""
-- Revert "move RW setup above user get in index.php so remember_me works"
-- move RW setup above user get in index.php so remember_me works
-- hide most DB_DataObject errors
-- always set up database_rw, regardless, so cached sessions work
-- update mysqltimestamps on insert and update
-- additional debugging data for Sessions
-- 'Sign in with Twitter' button img
-- Update to biz theme
-- Remove redundant session token field from form (was already being added by base class).
-- 'Sign in with Twitter' button img
-- Can now set $config['queue']['stomp_persistent'] = false; to explicitly disable persistence when we queue items
-- Showing processing indicator for form_repeat on submit instead of form
-- Removed avatar from repeat of username (matches noticelist)
-- Removed unused variable assignment for avatar URL and added missing fn
-- Don't preemptively close existing DB connections for web views (needed to keep # of conns from going insane on multi-site queue daemons, so just doing for CLI) May, or may not, help with mystery session problems
-- dropping the setcookie() call from common_ensure_session() since we're pretty sure it's unnecessary
-- append '/' on cookie path for now (may still need some refactoring)
-- set session cookie correctly
-- Fix for Mapstraction plugin's zoomed map links
-- debug log line for control channel sub
-- Move faceboookapp.js to the Facebook plugin
-- fix for fix for bad realtime JS load
-- default 24-hour expiry on Memcached objects where not specified.
+- Support for the new distributed status update standard OStatus
+ <http://ostatus.org>, based on PubSubHubbub, Salmon, Webfinger,
+ and Activity Streams.
+- Support for location. Notices are (optionally) marked with lat-long
+ information, and can be shown on a map.
+- No fixed content size. Notice size is configurable, from 1 to
+ unlimited number of characters. Default is still 140!
+- An authorization framework, allowing different levels of users.
+- A Web-based administration panel.
+- A moderation system that lets site moderators sandbox, silence,
+ or delete uncooperative users.
+- A flag system that lets users flag profiles for moderator review.
+- Support for OAuth <http://oauth.net> authentication in the Twitter
+ API.
+- A pluggable authentication system.
+- An authentication plugin for LDAP servers.
+- Many features that were core in 0.8.x are now plugins, such
+ as OpenID, Twitter integration, Facebook integration
+- A much-improved offline processing system
+- In-browser "realtime" updates using a number of realtime
+ servers (Meteor, Orbited, Cometd)
+- A plugin to provide an interface optimized for mobile browsers
+- Support for Facebook Connect
+- Support for logging in with a Twitter account
+- Vastly improved translation with additional languages and
+ translation in plugins
+- Support for all-SSL instances
+- Core support for "repeats" (like Twitter's "retweets")
+- Pluggable caching system, with plugins for Memcached,
+ APC, XCache, and a disk-based cache
+- Plugin to support RSSCloud
+- A framework for adding advertisements to a public site,
+ and plugins for Google AdSense and OpenX server
+
+There are also literally thousands of bugs fixed and minor features
+added. A full changelog is available at http://status.net/wiki/StatusNet_0.9.0.
+
+Under the covers, the software has a vastly improved plugin and
+extension mechanism that makes writing powerful and flexible additions
+to the core functionality much easier.
Prerequisites
=============
@@ -806,7 +654,7 @@ management, but host it on a public server.
Note that this is an experimental feature; total privacy is not
guaranteed or ensured. Also, privacy is all-or-nothing for a site; you
can't have some accounts or notices private, and others public.
-Finally, the interaction of private sites with OpenMicroBlogging is
+Finally, the interaction of private sites with OStatus is
undefined. Remote users won't be able to subscribe to users on a
private site, but users of the private site may be able to subscribe
to users on a remote site. (Or not... it's not well tested.) The
diff --git a/actions/sitenoticeadminpanel.php b/actions/sitenoticeadminpanel.php
index 613a2e96b..3931aa982 100644
--- a/actions/sitenoticeadminpanel.php
+++ b/actions/sitenoticeadminpanel.php
@@ -99,7 +99,7 @@ class SitenoticeadminpanelAction extends AdminPanelAction
$result = Config::save('site', 'notice', $siteNotice);
- if (!result) {
+ if (!$result) {
$this->ServerError(_("Unable to save site notice."));
}
}
diff --git a/db/08to09.sql b/db/08to09.sql
index c6c5d7af6..ba6f38200 100644
--- a/db/08to09.sql
+++ b/db/08to09.sql
@@ -111,7 +111,11 @@ alter table queue_item rename to queue_item_old;
alter table queue_item_new rename to queue_item;
alter table consumer
- add column consumer_secret varchar(255) not null comment 'secret value';
+ add consumer_secret varchar(255) not null comment 'secret value';
+
+alter table token
+ add verifier varchar(255) comment 'verifier string for OAuth 1.0a',
+ add verified_callback varchar(255) comment 'verified callback URL for OAuth 1.0a';
create table oauth_application (
id integer auto_increment primary key comment 'unique identifier',
@@ -140,8 +144,47 @@ create table oauth_application_user (
constraint primary key (profile_id, application_id)
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
+create table inbox (
+
+ user_id integer not null comment 'user receiving the notice' references user (id),
+ notice_ids blob comment 'packed list of notice ids',
+
+ constraint primary key (user_id)
+
+) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
+
+create table conversation (
+ id integer auto_increment primary key comment 'unique identifier',
+ uri varchar(225) unique comment 'URI of the conversation',
+ created datetime not null comment 'date this record was created',
+ modified timestamp comment 'date this record was modified'
+) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
+
+-- stub entry to push the autoincrement past existing notice ids
+insert into conversation (id,created)
+ select max(id)+1, now() from notice;
+
+alter table user_group
+ add uri varchar(255) unique key comment 'universal identifier',
+ add mainpage varchar(255) comment 'page for group info to link to',
+ drop index nickname;
+
+create table local_group (
+
+ group_id integer primary key comment 'group represented' references user_group (id),
+ nickname varchar(64) unique key comment 'group represented',
+
+ created datetime not null comment 'date this record was created',
+ modified timestamp comment 'date this record was modified'
+
+) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
+
+insert into local_group (group_id, nickname, created)
+ select id, nickname, created from user_group;
+
alter table file_to_post
add index post_id_idx (post_id);
alter table group_inbox
add index group_inbox_notice_id_idx (notice_id);
+
diff --git a/install.php b/install.php
index 41024c901..bb53e2b55 100644
--- a/install.php
+++ b/install.php
@@ -435,82 +435,119 @@ E_O_T;
E_O_T;
}
+/**
+ * Helper class for building form
+ */
+class Posted {
+ function value($name)
+ {
+ if (isset($_POST[$name])) {
+ return htmlspecialchars(strval($_POST[$name]));
+ } else {
+ return '';
+ }
+ }
+}
+
function showForm()
{
global $dbModules;
+ $post = new Posted();
$dbRadios = '';
- $checked = 'checked="checked" '; // Check the first one which exists
+ if (isset($_POST['dbtype'])) {
+ $dbtype = $_POST['dbtype'];
+ } else {
+ $dbtype = null;
+ }
foreach ($dbModules as $type => $info) {
if (checkExtension($info['check_module'])) {
+ if ($dbtype == null || $dbtype == $type) {
+ $checked = 'checked="checked" ';
+ $dbtype = $type; // if we didn't have one checked, hit the first
+ } else {
+ $checked = '';
+ }
$dbRadios .= "<input type=\"radio\" name=\"dbtype\" id=\"dbtype-$type\" value=\"$type\" $checked/> $info[name]<br />\n";
- $checked = '';
}
}
echo<<<E_O_T
</ul>
</dd>
</dl>
-<dl id="page_notice" class="system_notice">
- <dt>Page notice</dt>
- <dd>
- <div class="instructions">
- <p>Enter your database connection information below to initialize the database.</p>
- </div>
- </dd>
-</dl>
<form method="post" action="install.php" class="form_settings" id="form_install">
<fieldset>
- <legend>Connection settings</legend>
- <ul class="form_data">
- <li>
- <label for="sitename">Site name</label>
- <input type="text" id="sitename" name="sitename" />
- <p class="form_guide">The name of your site</p>
- </li>
- <li>
- <label for="fancy-enable">Fancy URLs</label>
- <input type="radio" name="fancy" id="fancy-enable" value="enable" checked='checked' /> enable<br />
- <input type="radio" name="fancy" id="fancy-disable" value="" /> disable<br />
- <p class="form_guide" id='fancy-form_guide'>Enable fancy (pretty) URLs. Auto-detection failed, it depends on Javascript.</p>
- </li>
- <li>
- <label for="host">Hostname</label>
- <input type="text" id="host" name="host" />
- <p class="form_guide">Database hostname</p>
- </li>
- <li>
-
- <label for="dbtype">Type</label>
- $dbRadios
- <p class="form_guide">Database type</p>
- </li>
-
- <li>
- <label for="database">Name</label>
- <input type="text" id="database" name="database" />
- <p class="form_guide">Database name</p>
- </li>
- <li>
- <label for="username">DB username</label>
- <input type="text" id="username" name="username" />
- <p class="form_guide">Database username</p>
- </li>
- <li>
- <label for="password">DB password</label>
- <input type="password" id="password" name="password" />
- <p class="form_guide">Database password (optional)</p>
- </li>
- <li>
- <label for="admin_nickname">Administrator nickname</label>
- <input type="text" id="admin_nickname" name="admin_nickname" />
- <p class="form_guide">Nickname for the initial StatusNet user (administrator)</p>
- </li>
- <li>
- <label for="initial_user_password">Administrator password</label>
- <input type="password" id="admin_password" name="admin_password" />
- <p class="form_guide">Password for the initial StatusNet user (administrator)</p>
- </li>
- </ul>
+ <fieldset id="settings_site">
+ <legend>Site settings</legend>
+ <ul class="form_data">
+ <li>
+ <label for="sitename">Site name</label>
+ <input type="text" id="sitename" name="sitename" value="{$post->value('sitename')}" />
+ <p class="form_guide">The name of your site</p>
+ </li>
+ <li>
+ <label for="fancy-enable">Fancy URLs</label>
+ <input type="radio" name="fancy" id="fancy-enable" value="enable" checked='checked' /> enable<br />
+ <input type="radio" name="fancy" id="fancy-disable" value="" /> disable<br />
+ <p class="form_guide" id='fancy-form_guide'>Enable fancy (pretty) URLs. Auto-detection failed, it depends on Javascript.</p>
+ </li>
+ </ul>
+ </fieldset>
+
+ <fieldset id="settings_db">
+ <legend>Database settings</legend>
+ <ul class="form_data">
+ <li>
+ <label for="host">Hostname</label>
+ <input type="text" id="host" name="host" value="{$post->value('host')}" />
+ <p class="form_guide">Database hostname</p>
+ </li>
+ <li>
+ <label for="dbtype">Type</label>
+ $dbRadios
+ <p class="form_guide">Database type</p>
+ </li>
+ <li>
+ <label for="database">Name</label>
+ <input type="text" id="database" name="database" value="{$post->value('database')}" />
+ <p class="form_guide">Database name</p>
+ </li>
+ <li>
+ <label for="dbusername">DB username</label>
+ <input type="text" id="dbusername" name="dbusername" value="{$post->value('dbusername')}" />
+ <p class="form_guide">Database username</p>
+ </li>
+ <li>
+ <label for="dbpassword">DB password</label>
+ <input type="password" id="dbpassword" name="dbpassword" value="{$post->value('dbpassword')}" />
+ <p class="form_guide">Database password (optional)</p>
+ </li>
+ </ul>
+ </fieldset>
+
+ <fieldset id="settings_admin">
+ <legend>Administrator settings</legend>
+ <ul class="form_data">
+ <li>
+ <label for="admin_nickname">Administrator nickname</label>
+ <input type="text" id="admin_nickname" name="admin_nickname" value="{$post->value('admin_nickname')}" />
+ <p class="form_guide">Nickname for the initial StatusNet user (administrator)</p>
+ </li>
+ <li>
+ <label for="admin_password">Administrator password</label>
+ <input type="password" id="admin_password" name="admin_password" value="{$post->value('admin_password')}" />
+ <p class="form_guide">Password for the initial StatusNet user (administrator)</p>
+ </li>
+ <li>
+ <label for="admin_password2">Confirm password</label>
+ <input type="password" id="admin_password2" name="admin_password2" value="{$post->value('admin_password2')}" />
+ </li>
+ <li>
+ <label for="admin_email">Administrator e-mail</label>
+ <input id="admin_email" name="admin_email" value="{$post->value('admin_email')}" />
+ <p class="form_guide">Optional email address for the initial StatusNet user (administrator)</p>
+ </li>
+ </ul>
+ </fieldset>
<input type="submit" name="submit" class="submit" value="Submit" />
</fieldset>
</form>
@@ -528,13 +565,15 @@ function handlePost()
$host = $_POST['host'];
$dbtype = $_POST['dbtype'];
$database = $_POST['database'];
- $username = $_POST['username'];
- $password = $_POST['password'];
+ $username = $_POST['dbusername'];
+ $password = $_POST['dbpassword'];
$sitename = $_POST['sitename'];
$fancy = !empty($_POST['fancy']);
$adminNick = $_POST['admin_nickname'];
$adminPass = $_POST['admin_password'];
+ $adminPass2 = $_POST['admin_password2'];
+ $adminEmail = $_POST['admin_email'];
$server = $_SERVER['HTTP_HOST'];
$path = substr(dirname($_SERVER['PHP_SELF']), 1);
@@ -576,6 +615,11 @@ STR;
updateStatus("No initial StatusNet user password specified.", true);
$fail = true;
}
+
+ if ($adminPass != $adminPass2) {
+ updateStatus("Administrator passwords do not match. Did you mistype?", true);
+ $fail = true;
+ }
if ($fail) {
showForm();
@@ -600,7 +644,7 @@ STR;
}
// Okay, cross fingers and try to register an initial user
- if (registerInitialUser($adminNick, $adminPass)) {
+ if (registerInitialUser($adminNick, $adminPass, $adminEmail)) {
updateStatus(
"An initial user with the administrator role has been created."
);
@@ -620,7 +664,7 @@ STR;
updateStatus("StatusNet has been installed at $link");
updateStatus(
- "You can visit your <a href='$link'>new StatusNet site</a> (login as '$adminNick')."
+ "<strong>DONE!</strong> You can visit your <a href='$link'>new StatusNet site</a> (login as '$adminNick'). If this is your first StatusNet install, you may want to poke around our <a href='http://status.net/wiki/Getting_started'>Getting Started guide</a>."
);
}
@@ -797,19 +841,20 @@ function runDbScript($filename, $conn, $type = 'mysqli')
return true;
}
-function registerInitialUser($nickname, $password)
+function registerInitialUser($nickname, $password, $email)
{
define('STATUSNET', true);
define('LACONICA', true); // compatibility
require_once INSTALLDIR . '/lib/common.php';
- $user = User::register(
- array('nickname' => $nickname,
- 'password' => $password,
- 'fullname' => $nickname
- )
- );
+ $data = array('nickname' => $nickname,
+ 'password' => $password,
+ 'fullname' => $nickname);
+ if ($email) {
+ $data['email'] = $email;
+ }
+ $user = User::register($data);
if (empty($user)) {
return false;
diff --git a/lib/activity.php b/lib/activity.php
index e1bce6f19..2cb80f9e1 100644
--- a/lib/activity.php
+++ b/lib/activity.php
@@ -344,16 +344,18 @@ class ActivityUtils
static function getLink(DOMNode $element, $rel, $type=null)
{
- $links = $element->getElementsByTagnameNS(self::ATOM, self::LINK);
+ $els = $element->childNodes;
- foreach ($links as $link) {
+ foreach ($els as $link) {
+ if ($link->localName == self::LINK && $link->namespaceURI == self::ATOM) {
- $linkRel = $link->getAttribute(self::REL);
- $linkType = $link->getAttribute(self::TYPE);
+ $linkRel = $link->getAttribute(self::REL);
+ $linkType = $link->getAttribute(self::TYPE);
- if ($linkRel == $rel &&
- (is_null($type) || $linkType == $type)) {
- return $link->getAttribute(self::HREF);
+ if ($linkRel == $rel &&
+ (is_null($type) || $linkType == $type)) {
+ return $link->getAttribute(self::HREF);
+ }
}
}
@@ -362,17 +364,19 @@ class ActivityUtils
static function getLinks(DOMNode $element, $rel, $type=null)
{
- $links = $element->getElementsByTagnameNS(self::ATOM, self::LINK);
+ $els = $element->childNodes;
$out = array();
- foreach ($links as $link) {
+ foreach ($els as $link) {
+ if ($link->localName == self::LINK && $link->namespaceURI == self::ATOM) {
- $linkRel = $link->getAttribute(self::REL);
- $linkType = $link->getAttribute(self::TYPE);
+ $linkRel = $link->getAttribute(self::REL);
+ $linkType = $link->getAttribute(self::TYPE);
- if ($linkRel == $rel &&
- (is_null($type) || $linkType == $type)) {
- $out[] = $link;
+ if ($linkRel == $rel &&
+ (is_null($type) || $linkType == $type)) {
+ $out[] = $link;
+ }
}
}
diff --git a/lib/adminpanelaction.php b/lib/adminpanelaction.php
index f3f86449f..a927e2333 100644
--- a/lib/adminpanelaction.php
+++ b/lib/adminpanelaction.php
@@ -194,16 +194,6 @@ class AdminPanelAction extends Action
}
/**
- * There is no data for aside, so, we don't output
- *
- * @return nothing
- */
- function showAside()
- {
-
- }
-
- /**
* show human-readable instructions for the page, or
* a success/failure on save.
*
diff --git a/lib/apiaction.php b/lib/apiaction.php
index eef0ba637..e4a1df3d1 100644
--- a/lib/apiaction.php
+++ b/lib/apiaction.php
@@ -86,7 +86,7 @@ class ApiAction extends Action
$this->since_id = (int)$this->arg('since_id', 0);
if ($this->arg('since')) {
- $this->clientError(_("since parameter is disabled for performance; use since_id"), 403);
+ header('X-StatusNet-Warning: since parameter is disabled; use since_id');
}
return true;
diff --git a/lib/default.php b/lib/default.php
index c46c3eef5..f22d8b24a 100644
--- a/lib/default.php
+++ b/lib/default.php
@@ -280,6 +280,7 @@ $default =
'TightUrl' => array('shortenerName' => '2tu.us', 'freeService' => true,'serviceUrl'=>'http://2tu.us/?save=y&url=%1$s'),
'Geonames' => null,
'Mapstraction' => null,
+ 'OStatus' => null,
'WikiHashtags' => null,
'RSSCloud' => null,
'OpenID' => null),
diff --git a/plugins/OStatus/OStatusPlugin.php b/plugins/OStatus/OStatusPlugin.php
index 033325c9e..efb630297 100644
--- a/plugins/OStatus/OStatusPlugin.php
+++ b/plugins/OStatus/OStatusPlugin.php
@@ -836,4 +836,17 @@ class OStatusPlugin extends Plugin
return true;
}
+
+ function onPluginVersion(&$versions)
+ {
+ $versions[] = array('name' => 'OStatus',
+ 'version' => STATUSNET_VERSION,
+ 'author' => 'Evan Prodromou, James Walker, Brion Vibber, Zach Copley',
+ 'homepage' => 'http://status.net/wiki/Plugin:OStatus',
+ 'rawdescription' =>
+ _m('Follow people across social networks that implement '.
+ '<a href="http://ostatus.org/">OStatus</a>.'));
+
+ return true;
+ }
}
diff --git a/plugins/OStatus/actions/ostatusinit.php b/plugins/OStatus/actions/ostatusinit.php
index 1e45025b0..22aea9f70 100644
--- a/plugins/OStatus/actions/ostatusinit.php
+++ b/plugins/OStatus/actions/ostatusinit.php
@@ -186,7 +186,7 @@ class OStatusInitAction extends Action
$this->clientError("No such user.");
}
} else if ($this->group) {
- $group = Local_group::staticGet('id', $this->group);
+ $group = Local_group::staticGet('nickname', $this->group);
if ($group) {
return common_local_url('groupbyid', array('id' => $group->group_id));
} else {
diff --git a/plugins/PubSubHubBub/PubSubHubBubPlugin.php b/plugins/PubSubHubBub/PubSubHubBubPlugin.php
deleted file mode 100644
index a880dc866..000000000
--- a/plugins/PubSubHubBub/PubSubHubBubPlugin.php
+++ /dev/null
@@ -1,285 +0,0 @@
-<?php
-/**
- * StatusNet, the distributed open-source microblogging tool
- *
- * Plugin to push RSS/Atom updates to a PubSubHubBub hub
- *
- * PHP version 5
- *
- * LICENCE: 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 Craig Andrews <candrews@integralblue.com>
- * @copyright 2009 Craig Andrews http://candrews.integralblue.com
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link http://status.net/
- */
-
-if (!defined('STATUSNET')) {
- exit(1);
-}
-
-define('DEFAULT_HUB', 'http://pubsubhubbub.appspot.com');
-
-require_once INSTALLDIR.'/plugins/PubSubHubBub/publisher.php';
-
-/**
- * Plugin to provide publisher side of PubSubHubBub (PuSH)
- * relationship.
- *
- * PuSH is a real-time or near-real-time protocol for Atom
- * and RSS feeds. More information here:
- *
- * http://code.google.com/p/pubsubhubbub/
- *
- * To enable, add the following line to your config.php:
- *
- * addPlugin('PubSubHubBub');
- *
- * This will use the Google default hub. If you'd like to use
- * another, try:
- *
- * addPlugin('PubSubHubBub',
- * array('hub' => 'http://yourhub.example.net/'));
- *
- * @category Plugin
- * @package StatusNet
- * @author Craig Andrews <candrews@integralblue.com>
- * @copyright 2009 Craig Andrews http://candrews.integralblue.com
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3
- * @link http://status.net/
- */
-
-class PubSubHubBubPlugin extends Plugin
-{
- /**
- * URL of the hub to advertise and publish to.
- */
-
- public $hub = DEFAULT_HUB;
-
- /**
- * Default constructor.
- */
-
- function __construct()
- {
- parent::__construct();
- }
-
- /**
- * Check if plugin should be active; may be mass-enabled.
- * @return boolean
- */
-
- function enabled()
- {
- if (common_config('site', 'private')) {
- // PuSH relies on public feeds
- return false;
- }
- // @fixme check for being on a private network?
- return true;
- }
-
- /**
- * Hooks the StartApiAtom event
- *
- * Adds the necessary bits to advertise PubSubHubBub
- * for the Atom feed.
- *
- * @param Action $action The API action being shown.
- *
- * @return boolean hook value
- */
-
- function onStartApiAtom($action)
- {
- if ($this->enabled()) {
- $action->element('link', array('rel' => 'hub', 'href' => $this->hub), null);
- }
- return true;
- }
-
- /**
- * Hooks the StartApiRss event
- *
- * Adds the necessary bits to advertise PubSubHubBub
- * for the RSS 2.0 feeds.
- *
- * @param Action $action The API action being shown.
- *
- * @return boolean hook value
- */
-
- function onStartApiRss($action)
- {
- if ($this->enabled()) {
- $action->element('atom:link', array('rel' => 'hub',
- 'href' => $this->hub),
- null);
- }
- return true;
- }
-
- /**
- * Hook for a queued notice.
- *
- * When a notice has been queued, will ping the
- * PuSH hub for each Atom and RSS feed in which
- * the notice appears.
- *
- * @param Notice $notice The notice that's been queued
- *
- * @return boolean hook value
- */
-
- function onHandleQueuedNotice($notice)
- {
- if (!$this->enabled()) {
- return false;
- }
- $publisher = new Publisher($this->hub);
-
- $feeds = array();
-
- //public timeline feeds
- $feeds[] = common_local_url('ApiTimelinePublic', array('format' => 'rss'));
- $feeds[] = common_local_url('ApiTimelinePublic', array('format' => 'atom'));
-
- //author's own feeds
- $user = User::staticGet('id', $notice->profile_id);
-
- $feeds[] = common_local_url('ApiTimelineUser',
- array('id' => $user->nickname,
- 'format' => 'rss'));
- $feeds[] = common_local_url('ApiTimelineUser',
- array('id' => $user->nickname,
- 'format' => 'atom'));
-
- //tag feeds
- $tag = new Notice_tag();
-
- $tag->notice_id = $notice->id;
- if ($tag->find()) {
- while ($tag->fetch()) {
- $feeds[] = common_local_url('ApiTimelineTag',
- array('tag' => $tag->tag,
- 'format' => 'rss'));
- $feeds[] = common_local_url('ApiTimelineTag',
- array('tag' => $tag->tag,
- 'format' => 'atom'));
- }
- }
-
- //group feeds
- $group_inbox = new Group_inbox();
-
- $group_inbox->notice_id = $notice->id;
- if ($group_inbox->find()) {
- while ($group_inbox->fetch()) {
- $group = User_group::staticGet('id', $group_inbox->group_id);
-
- $feeds[] = common_local_url('ApiTimelineGroup',
- array('id' => $group->nickname,
- 'format' => 'rss'));
- $feeds[] = common_local_url('ApiTimelineGroup',
- array('id' => $group->nickname,
- 'format' => 'atom'));
- }
- }
-
- //feed of each user that subscribes to the notice's author
-
- $ni = $notice->whoGets();
-
- foreach (array_keys($ni) as $user_id) {
- $user = User::staticGet('id', $user_id);
- if (empty($user)) {
- continue;
- }
- $feeds[] = common_local_url('ApiTimelineFriends',
- array('id' => $user->nickname,
- 'format' => 'rss'));
- $feeds[] = common_local_url('ApiTimelineFriends',
- array('id' => $user->nickname,
- 'format' => 'atom'));
- }
-
- $replies = $notice->getReplies();
-
- //feed of user replied to
- foreach ($replies as $recipient) {
- $user = User::staticGet('id', $recipient);
- if (!empty($user)) {
- $feeds[] = common_local_url('ApiTimelineMentions',
- array('id' => $user->nickname,
- 'format' => 'rss'));
- $feeds[] = common_local_url('ApiTimelineMentions',
- array('id' => $user->nickname,
- 'format' => 'atom'));
- }
- }
- $feeds = array_unique($feeds);
-
- ob_start();
- $ok = $publisher->publish_update($feeds);
- $push_last_response = ob_get_clean();
-
- if (!$ok) {
- common_log(LOG_WARNING,
- 'Failure publishing ' . count($feeds) . ' feeds to hub at '.
- $this->hub.': '.$push_last_response);
- } else {
- common_log(LOG_INFO,
- 'Published ' . count($feeds) . ' feeds to hub at '.
- $this->hub.': '.$push_last_response);
- }
-
- return true;
- }
-
- /**
- * Provide version information
- *
- * Adds this plugin's version data to the global
- * version array, for e.g. displaying on the version page.
- *
- * @param array &$versions array of array of versions
- *
- * @return boolean hook value
- */
-
- function onPluginVersion(&$versions)
- {
- $about = _m('The PubSubHubBub plugin pushes RSS/Atom updates '.
- 'to a <a href = "'.
- 'http://pubsubhubbub.googlecode.com/'.
- '">PubSubHubBub</a> hub.');
- if (!$this->enabled()) {
- $about = '<span class="disabled" style="color:gray">' . $about . '</span> ' .
- _m('(inactive on private site)');
- }
- $versions[] = array('name' => 'PubSubHubBub',
- 'version' => STATUSNET_VERSION,
- 'author' => 'Craig Andrews',
- 'homepage' =>
- 'http://status.net/wiki/Plugin:PubSubHubBub',
- 'rawdescription' =>
- $about);
-
- return true;
- }
-}
diff --git a/plugins/PubSubHubBub/publisher.php b/plugins/PubSubHubBub/publisher.php
deleted file mode 100644
index f176a9b8a..000000000
--- a/plugins/PubSubHubBub/publisher.php
+++ /dev/null
@@ -1,86 +0,0 @@
-<?php
-
-// a PHP client library for pubsubhubbub
-// as defined at http://code.google.com/p/pubsubhubbub/
-// written by Josh Fraser | joshfraser.com | josh@eventvue.com
-// Released under Apache License 2.0
-
-class Publisher {
-
- protected $hub_url;
- protected $last_response;
-
- // create a new Publisher
- public function __construct($hub_url) {
-
- if (!isset($hub_url))
- throw new Exception('Please specify a hub url');
-
- if (!preg_match("|^https?://|i",$hub_url))
- throw new Exception('The specified hub url does not appear to be valid: '.$hub_url);
-
- $this->hub_url = $hub_url;
- }
-
- // accepts either a single url or an array of urls
- public function publish_update($topic_urls, $http_function = false) {
- if (!isset($topic_urls))
- throw new Exception('Please specify a topic url');
-
- // check that we're working with an array
- if (!is_array($topic_urls)) {
- $topic_urls = array($topic_urls);
- }
-
- // set the mode to publish
- $post_string = "hub.mode=publish";
- // loop through each topic url
- foreach ($topic_urls as $topic_url) {
-
- // lightweight check that we're actually working w/ a valid url
- if (!preg_match("|^https?://|i",$topic_url))
- throw new Exception('The specified topic url does not appear to be valid: '.$topic_url);
-
- // append the topic url parameters
- $post_string .= "&hub.url=".urlencode($topic_url);
- }
-
- // make the http post request and return true/false
- // easy to over-write to use your own http function
- if ($http_function)
- return $http_function($this->hub_url,$post_string);
- else
- return $this->http_post($this->hub_url,$post_string);
- }
-
- // returns any error message from the latest request
- public function last_response() {
- return $this->last_response;
- }
-
- // default http function that uses curl to post to the hub endpoint
- private function http_post($url, $post_string) {
-
- // add any additional curl options here
- $options = array(CURLOPT_URL => $url,
- CURLOPT_POST => true,
- CURLOPT_POSTFIELDS => $post_string,
- CURLOPT_USERAGENT => "PubSubHubbub-Publisher-PHP/1.0");
-
- $ch = curl_init();
- curl_setopt_array($ch, $options);
-
- $response = curl_exec($ch);
- $this->last_response = $response;
- $info = curl_getinfo($ch);
-
- curl_close($ch);
-
- // all good
- if ($info['http_code'] == 204)
- return true;
- return false;
- }
-}
-
-?> \ No newline at end of file
diff --git a/scripts/setup_status_network.sh b/scripts/setup_status_network.sh
index 89d15415f..4ebb696c7 100755
--- a/scripts/setup_status_network.sh
+++ b/scripts/setup_status_network.sh
@@ -54,6 +54,8 @@ for top in $AVATARBASE $FILEBASE $BACKGROUNDBASE; do
chmod a+w $top/$nickname
done
+php $PHPBASE/scripts/checkschema.php -s"$server"
+
php $PHPBASE/scripts/registeruser.php \
-s"$server" \
-n"$nickname" \
diff --git a/theme/base/css/display.css b/theme/base/css/display.css
index 01d5dd134..964755832 100644
--- a/theme/base/css/display.css
+++ b/theme/base/css/display.css
@@ -345,10 +345,14 @@ list-style-type:none;
float:left;
text-decoration:none;
padding:4px 11px;
+border-radius-topleft:4px;
+border-radius-topright:4px;
-moz-border-radius-topleft:4px;
-moz-border-radius-topright:4px;
-webkit-border-top-left-radius:4px;
-webkit-border-top-right-radius:4px;
+border-radius-topleft:0;
+border-radius-topright:0;
border-width:1px;
border-style:solid;
border-bottom:0;
@@ -359,6 +363,56 @@ float:left;
width:100%;
}
+body[id$=adminpanel] #site_nav_local_views {
+float:right;
+margin-right:18.9%;
+
+margin-right:189px;
+position:relative;
+width:14.01%;
+
+width:141px;
+z-index:9;
+}
+body[id$=adminpanel] #site_nav_local_views li {
+width:100%;
+margin-right:0;
+margin-bottom:7px;
+}
+body[id$=adminpanel] #site_nav_local_views a {
+display:block;
+width:100%;
+border-radius-toprleft:0;
+-moz-border-radius-topleft:0;
+-webkit-border-top-left-radius:0;
+border-radius-topright:4px;
+-moz-border-radius-topright:4px;
+-webkit-border-top-right-radius:4px;
+border-radius-bottomright:4px;
+-moz-border-radius-bottomright:4px;
+-webkit-border-bottom-right-radius:4px;
+}
+body[id$=adminpanel] #site_nav_local_views li.current {
+box-shadow:none;
+-moz-box-shadow:none;
+-webkit-box-shadow:none;
+}
+
+body[id$=adminpanel] #content {
+border-radius-topleft:7px;
+border-radius-topright:7px;
+-moz-border-radius-topleft:7px;
+-moz-border-radius-topright:7px;
+-webkit-border-top-left-radius:7px;
+-webkit-border-top-right-radius:7px;
+border-radius-topright:0;
+-moz-border-radius-topright:0;
+-webkit-border-top-right-radius:0;
+}
+body[id$=adminpanel] #aside_primary {
+display:none;
+}
+
#site_nav_global_primary dt,
#site_nav_global_secondary dt {
display:none;
@@ -452,13 +506,6 @@ width:100%;
float:left;
}
-#content.admin {
-width:95.5%;
-}
-#content.admin #content_inner {
-width:66.3%;
-}
-
#aside_primary {
width:27.917%;
min-height:259px;