summaryrefslogtreecommitdiff
path: root/plugins/RSSCloud
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/RSSCloud')
-rw-r--r--plugins/RSSCloud/LoggingAggregator.php30
-rw-r--r--plugins/RSSCloud/RSSCloudNotifier.php52
-rw-r--r--plugins/RSSCloud/RSSCloudPlugin.php63
-rw-r--r--plugins/RSSCloud/RSSCloudRequestNotify.php85
4 files changed, 222 insertions, 8 deletions
diff --git a/plugins/RSSCloud/LoggingAggregator.php b/plugins/RSSCloud/LoggingAggregator.php
index 02175f43a..c81a987f7 100644
--- a/plugins/RSSCloud/LoggingAggregator.php
+++ b/plugins/RSSCloud/LoggingAggregator.php
@@ -32,6 +32,19 @@ if (!defined('STATUSNET')) {
exit(1);
}
+/**
+ * Dummy aggregator that acts as a proper notification handler. It
+ * doesn't do anything but respond correctly when notified via
+ * REST. Mostly, this is just and action I used to develop the plugin
+ * and easily test things end-to-end. I'm leaving it in here as it
+ * may be useful for developing the plugin further.
+ *
+ * @category Plugin
+ * @package StatusNet
+ * @author Zach Copley <zach@status.net>
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ **/
class LoggingAggregatorAction extends Action
{
@@ -45,6 +58,7 @@ class LoggingAggregatorAction extends Action
*
* @return boolean false if user doesn't exist
*/
+
function prepare($args)
{
parent::prepare($args);
@@ -58,6 +72,14 @@ class LoggingAggregatorAction extends Action
return true;
}
+ /**
+ * Handle the request
+ *
+ * @param array $args $_REQUEST data (unused)
+ *
+ * @return void
+ */
+
function handle($args)
{
parent::handle($args);
@@ -98,6 +120,14 @@ class LoggingAggregatorAction extends Action
$this->url . ' has been updated.');
}
+ /**
+ * Show an XML error when things go badly
+ *
+ * @param string $msg the error message
+ *
+ * @return void
+ */
+
function showError($msg)
{
header('HTTP/1.1 400 Bad Request');
diff --git a/plugins/RSSCloud/RSSCloudNotifier.php b/plugins/RSSCloud/RSSCloudNotifier.php
index 909cf5c9f..485c4dcdf 100644
--- a/plugins/RSSCloud/RSSCloudNotifier.php
+++ b/plugins/RSSCloud/RSSCloudNotifier.php
@@ -31,10 +31,29 @@ if (!defined('STATUSNET')) {
exit(1);
}
+/**
+ * Class for notifying cloud-enabled RSS aggregators that StatusNet
+ * feeds have been updated.
+ *
+ * @category Plugin
+ * @package StatusNet
+ * @author Zach Copley <zach@status.net>
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ **/
class RSSCloudNotifier {
const MAX_FAILURES = 3;
+ /**
+ * Send an HTTP GET to the notification handler with a
+ * challenge string to see if it repsonds correctly.
+ *
+ * @param String $endpoint URL of the notification handler
+ * @param String $feed the feed being subscribed to
+ *
+ * @return boolean success
+ */
function challenge($endpoint, $feed)
{
$code = common_confirmation_code(128);
@@ -60,7 +79,7 @@ class RSSCloudNotifier {
// NOTE: the spec says that the body must contain the string
// challenge. It doesn't say that the body must contain the
// challenge string ONLY, although that seems to be the way
- // the other implementations have interpreted it.
+ // the other implementors have interpreted it.
if (strpos($body, $code) !== false) {
common_log(LOG_INFO, 'RSSCloud plugin - ' .
@@ -82,6 +101,15 @@ class RSSCloudNotifier {
}
}
+ /**
+ * HTTP POST a notification that a feed has been updated
+ * ('ping the cloud').
+ *
+ * @param String $endpoint URL of the notification handler
+ * @param String $feed the feed being subscribed to
+ *
+ * @return boolean success
+ */
function postUpdate($endpoint, $feed) {
$headers = array();
@@ -111,6 +139,14 @@ class RSSCloudNotifier {
}
}
+ /**
+ * Notify all subscribers to a profile feed that it has changed.
+ *
+ * @param Profile $profile the profile whose feed has been
+ * updated
+ *
+ * @return boolean success
+ */
function notify($profile)
{
$feed = common_path('api/statuses/user_timeline/') .
@@ -131,6 +167,18 @@ class RSSCloudNotifier {
return true;
}
+ /**
+ * Handle problems posting cloud notifications. Increment the failure
+ * count, or delete the subscription if the maximum number of failures
+ * is exceeded.
+ *
+ * XXX: Redo with proper DB_DataObject methods once I figure out what
+ * what the problem is with pluginized DB_DataObjects. -Z
+ *
+ * @param RSSCloudSubscription $cloudSub the subscription in question
+ *
+ * @return boolean success
+ */
function handleFailure($cloudSub)
{
$failCnt = $cloudSub->failures + 1;
@@ -172,8 +220,6 @@ class RSSCloudNotifier {
' WHERE subscribed = ' . $cloudSub->subscribed .
' AND url = \'' . $cloudSub->url . '\'';
- common_debug($qry);
-
$result = $cloudSub->query($qry);
if (!$result) {
diff --git a/plugins/RSSCloud/RSSCloudPlugin.php b/plugins/RSSCloud/RSSCloudPlugin.php
index fcd468f55..8c0bfa904 100644
--- a/plugins/RSSCloud/RSSCloudPlugin.php
+++ b/plugins/RSSCloud/RSSCloudPlugin.php
@@ -31,15 +31,35 @@ if (!defined('STATUSNET')) {
exit(1);
}
-define('RSSCLOUDPLUGIN_VERSION', '0.1');
+/**
+ * Plugin class for adding RSSCloud capabilities to StatusNet
+ *
+ * @category Plugin
+ * @package StatusNet
+ * @author Zach Copley <zach@status.net>
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ **/
class RSSCloudPlugin extends Plugin
{
+ /**
+ * Our friend, the constructor
+ *
+ * @return void
+ */
function __construct()
{
parent::__construct();
}
+ /**
+ * Setup the info for the subscription handler. Allow overriding
+ * to point at another cloud hub (not currently used).
+ *
+ * @return void
+ */
+
function onInitializePlugin()
{
$this->domain = common_config('rsscloud', 'domain');
@@ -91,6 +111,16 @@ class RSSCloudPlugin extends Plugin
return true;
}
+ /**
+ * Automatically load the actions and libraries used by
+ * the RSSCloud plugin
+ *
+ * @param Class $cls the class
+ *
+ * @return boolean hook return
+ *
+ */
+
function onAutoload($cls)
{
switch ($cls)
@@ -110,10 +140,17 @@ class RSSCloudPlugin extends Plugin
}
}
+ /**
+ * Add a <cloud> element to the RSS feed (after the rss <channel>
+ * element is started).
+ *
+ * @param Action $action
+ *
+ * @return void
+ */
+
function onStartApiRss($action)
{
- // XXX: Add RSS 1.0 user feeds
-
if (get_class($action) == 'ApiTimelineUserAction') {
$attrs = array('domain' => $this->domain,
@@ -141,6 +178,7 @@ class RSSCloudPlugin extends Plugin
*
* @return boolean hook return
*/
+
function onStartEnqueueNotice($notice, &$transports)
{
array_push($transports, 'rsscloud');
@@ -155,6 +193,7 @@ class RSSCloudPlugin extends Plugin
*
* @return boolean hook return
*/
+
function onUnqueueHandleNotice(&$notice, $queue)
{
if (($queue == 'rsscloud') && ($this->_isLocal($notice))) {
@@ -179,12 +218,20 @@ class RSSCloudPlugin extends Plugin
*
* @return boolean locality
*/
+
function _isLocal($notice)
{
return ($notice->is_local == Notice::LOCAL_PUBLIC ||
$notice->is_local == Notice::LOCAL_NONPUBLIC);
}
+ /**
+ * Create the rsscloud_subscription table if it's not
+ * already in the DB
+ *
+ * @return boolean hook return
+ */
+
function onCheckSchema() {
$schema = Schema::get();
$schema->ensureTable('rsscloud_subscription',
@@ -205,6 +252,16 @@ class RSSCloudPlugin extends Plugin
return true;
}
+ /**
+ * Add RSSCloudQueueHandler to the list of valid daemons to
+ * start
+ *
+ * @param array $daemons the list of daemons to run
+ *
+ * @return boolean hook return
+ *
+ */
+
function onGetValidDaemons($daemons)
{
array_push($daemons, INSTALLDIR .
diff --git a/plugins/RSSCloud/RSSCloudRequestNotify.php b/plugins/RSSCloud/RSSCloudRequestNotify.php
index 36959755a..4703ecd10 100644
--- a/plugins/RSSCloud/RSSCloudRequestNotify.php
+++ b/plugins/RSSCloud/RSSCloudRequestNotify.php
@@ -32,6 +32,16 @@ if (!defined('STATUSNET')) {
exit(1);
}
+/**
+ * Action class to handle RSSCloud notification (subscription) requests
+ *
+ * @category Plugin
+ * @package StatusNet
+ * @author Zach Copley <zach@status.net>
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ **/
+
class RSSCloudRequestNotifyAction extends Action
{
/**
@@ -41,6 +51,7 @@ class RSSCloudRequestNotifyAction extends Action
*
* @return boolean false if user doesn't exist
*/
+
function prepare($args)
{
parent::prepare($args);
@@ -62,6 +73,18 @@ class RSSCloudRequestNotifyAction extends Action
return true;
}
+ /**
+ * Handle the request
+ *
+ * Checks for all the required parameters for a subscription,
+ * validates that the feed being subscribed to is real, and then
+ * saves the subsctiption.
+ *
+ * @param array $args $_REQUEST data (unused)
+ *
+ * @return void
+ */
+
function handle($args)
{
parent::handle($args);
@@ -137,6 +160,15 @@ class RSSCloudRequestNotifyAction extends Action
$this->showResult(true, $msg);
}
+ /**
+ * Validate that the requested feed is one we serve
+ * up via RSSCloud.
+ *
+ * @param string $feed the feed in question
+ *
+ * @return void
+ */
+
function validateFeed($feed)
{
$user = $this->userFromFeed($feed);
@@ -148,6 +180,13 @@ class RSSCloudRequestNotifyAction extends Action
return true;
}
+ /**
+ * Pull all of the urls (url1, url2, url3...urlN) that
+ * the subscriber wants to subscribe to.
+ *
+ * @return array $feeds the list of feeds
+ */
+
function getFeeds()
{
$feeds = array();
@@ -161,6 +200,15 @@ class RSSCloudRequestNotifyAction extends Action
return $feeds;
}
+ /**
+ * Test that a notification handler is there and is reponding
+ * correctly. This is called before adding a subscription.
+ *
+ * @param string $feed the feed to verify
+ *
+ * @return boolean success result
+ */
+
function testNotificationHandler($feed)
{
common_debug("RSSCloudPlugin - testNotificationHandler()");
@@ -185,6 +233,13 @@ class RSSCloudRequestNotifyAction extends Action
}
}
+ /**
+ * Build the URL for the notification handler based on the
+ * parameters passed in with the subscription request.
+ *
+ * @return string notification handler url
+ */
+
function getNotifyUrl()
{
if (isset($this->domain)) {
@@ -194,12 +249,20 @@ class RSSCloudRequestNotifyAction extends Action
}
}
+ /**
+ * Uses the nickname part of the subscribed feed URL to figure out
+ * whethere there's really a user with such a feed. Used to
+ * validate feeds before adding a subscription.
+ *
+ * @param string $feed the feed in question
+ *
+ * @return boolean success
+ */
+
function userFromFeed($feed)
{
// We only do profile feeds
- // XXX: Add cloud element to RSS 1.0 feeds?
-
$path = common_path('api/statuses/user_timeline/');
$valid = '%^' . $path . '(?<nickname>.*)\.rss$%';
@@ -213,6 +276,14 @@ class RSSCloudRequestNotifyAction extends Action
return false;
}
+ /**
+ * Save an RSSCloud subscription
+ *
+ * @param $feed a valid profile feed
+ *
+ * @return boolean success result
+ */
+
function saveSubscription($feed)
{
$user = $this->userFromFeed($feed);
@@ -241,6 +312,16 @@ class RSSCloudRequestNotifyAction extends Action
return true;
}
+ /**
+ * Show an XML message indicating the subscription
+ * was successful or failed.
+ *
+ * @param boolean $success whether it was good or bad
+ * @param string $msg the message to output
+ *
+ * @return boolean success result
+ */
+
function showResult($success, $msg)
{
$this->startXML();