diff options
-rw-r--r-- | README | 262 | ||||
-rw-r--r-- | actions/sitenoticeadminpanel.php | 2 | ||||
-rw-r--r-- | db/08to09.sql | 45 | ||||
-rw-r--r-- | install.php | 189 | ||||
-rw-r--r-- | lib/activity.php | 32 | ||||
-rw-r--r-- | lib/adminpanelaction.php | 10 | ||||
-rw-r--r-- | lib/apiaction.php | 2 | ||||
-rw-r--r-- | lib/default.php | 1 | ||||
-rw-r--r-- | plugins/OStatus/OStatusPlugin.php | 13 | ||||
-rw-r--r-- | plugins/OStatus/actions/ostatusinit.php | 2 | ||||
-rw-r--r-- | plugins/PubSubHubBub/PubSubHubBubPlugin.php | 285 | ||||
-rw-r--r-- | plugins/PubSubHubBub/publisher.php | 86 | ||||
-rwxr-xr-x | scripts/setup_status_network.sh | 2 | ||||
-rw-r--r-- | theme/base/css/display.css | 61 |
14 files changed, 307 insertions, 685 deletions
@@ -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; |