]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Initial support for third-party fallback hub such as Superfeedr for feed subscriptions.
authorBrion Vibber <brion@pobox.com>
Mon, 2 Aug 2010 23:08:54 +0000 (16:08 -0700)
committerBrion Vibber <brion@status.net>
Tue, 10 Aug 2010 19:57:40 +0000 (12:57 -0700)
If set up, this hub will be used to subscribe to feeds that don't specify a hub of their own.
Assumes that the fallback hub will, in fact, handle polling and updates for any feed we throw at it!
Authentication may be specified for the fallback hub.

Example:

  $config['feedsub']['fallback_hub'] = 'https://superfeedr.com/hubbub';
  $config['feedsub']['hub_user'] = 'abcd';
  $config['feedsub']['hub_pass'] = 'ckcmdkmckdmkcdk';

Also:
* Fix for WordPress-RSS-via-Superfeedr-Atom; if we have <author> info but no ID from a native ActivityStreams actor, don't freak out in the low-level processing code that checks for identity matches.
* enhanced messages for low-level FeedSub exceptions if they make it to outside display

plugins/OStatus/OStatusPlugin.php
plugins/OStatus/README
plugins/OStatus/classes/FeedSub.php
plugins/OStatus/classes/Ostatus_profile.php
plugins/OStatus/lib/feeddiscovery.php
plugins/OStatus/scripts/update-profile.php

index 3b073a5d13dd8e19f38c960a586e43c96c10febc..6fef20d6f59172a085d345445ced56adce66a8ca 100644 (file)
@@ -28,6 +28,15 @@ set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/ext
 
 class FeedSubException extends Exception
 {
+    function __construct($msg=null)
+    {
+        $type = get_class($this);
+        if ($msg) {
+            parent::__construct("$type: $msg");
+        } else {
+            parent::__construct($type);
+        }
+    }
 }
 
 class OStatusPlugin extends Plugin
index 3a98b7b256b131067896838c819ce07c97529e7f..ea5dfc055f8f008553fd18b896e99a2441c3d297 100644 (file)
@@ -1,18 +1,42 @@
-Plugin to support importing updates from external RSS and Atom feeds into your timeline.
+Plugin to support importing and exporting notices through Atom and RSS feeds.
+The OStatus plugin concentrates on user-to-user cases for federating StatusNet
+and similar social networking / microblogging / blogging sites, but includes
+low-level feed subscription systems which are used by some other plugins.
+
+Uses PubSubHubbub for push feed updates; currently non-PuSH feeds cannot be
+subscribed unless an external PuSH hub proxy is used.
 
-Uses PubSubHubbub for push feed updates; currently non-PuSH feeds cannot be subscribed.
 
 Configuration options available:
 
 $config['ostatus']['hub']
     (default internal hub)
-    Set to URL of an external PuSH hub to use it instead of our internal hub.
+    Set to URL of an external PuSH hub to use it instead of our internal hub
+    for sending outgoing updates in user and group feeds.
 
 $config['ostatus']['hub_retries']
     (default 0)
     Number of times to retry a PuSH send to consumers if using internal hub
 
 
+Settings controlling incoming feed subscription:
+
+$config['feedsub']['fallback_hub']
+    To subscribe to feeds that don't have a hub, an external PuSH proxy hub
+    such as Superfeedr may be used. Any feed without a hub of its own will
+    be subscribed through the specified hub URL instead. If the external hub
+    has usage charges, be aware that there is no restriction placed to how
+    many feeds may be subscribed!
+
+    $config['feedsub']['fallback_hub'] = 'https://superfeedr.com/hubbub';
+
+$config['feedsub']['hub_user']
+$config['feedsub']['hub_password']
+    If using the fallback hub mode, these settings may be used to provide
+    HTTP authentication credentials for contacting the hub. Default hubs
+    specified from feeds are assumed to not require
+
+
 For testing, shouldn't be used in production:
 
 $config['ostatus']['skip_signatures']
@@ -23,12 +47,11 @@ $config['feedsub']['nohub']
     (default require hub)
     Allow low-level feed subscription setup for feeds without hubs.
     Not actually usable at this stage, OStatus will check for hubs too
-    and we have no polling backend.
+    and we have no polling backend. (The fallback hub option can be used
+    with a 3rd-party service to provide such polling.)
 
 
 Todo:
-* fully functional l10n
-* redo non-OStatus feed support
-** rssCloud support?
-** possibly a polling daemon to support non-PuSH feeds?
+* better support for feeds that aren't natively oriented at social networking
 * make use of tags/categories from feeds
+* better repeat handling
index 9cd35e29c9fa51c46d76538bae8187b843eea418..dd1968db12a52c3173d84f38f7e8c343a173a8ef 100644 (file)
@@ -207,8 +207,8 @@ class FeedSub extends Memcached_DataObject
         $discover = new FeedDiscovery();
         $discover->discoverFromFeedURL($feeduri);
 
-        $huburi = $discover->getAtomLink('hub');
-        if (!$huburi) {
+        $huburi = $discover->getHubLink();
+        if (!$huburi && !common_config('feedsub', 'fallback_hub')) {
             throw new FeedSubNoHubException();
         }
 
@@ -241,8 +241,12 @@ class FeedSub extends Memcached_DataObject
             common_log(LOG_WARNING, "Attempting to (re)start PuSH subscription to $this->uri in unexpected state $this->sub_state");
         }
         if (empty($this->huburi)) {
-            if (common_config('feedsub', 'nohub')) {
+            if (common_config('feedsub', 'fallback_hub')) {
+                // No native hub on this feed?
+                // Use our fallback hub, which handles polling on our behalf.
+            } else if (common_config('feedsub', 'nohub')) {
                 // Fake it! We're just testing remote feeds w/o hubs.
+                // We'll never actually get updates in this mode.
                 return true;
             } else {
                 throw new ServerException("Attempting to start PuSH subscription for feed with no hub");
@@ -267,8 +271,12 @@ class FeedSub extends Memcached_DataObject
             common_log(LOG_WARNING, "Attempting to (re)end PuSH subscription to $this->uri in unexpected state $this->sub_state");
         }
         if (empty($this->huburi)) {
-            if (common_config('feedsub', 'nohub')) {
+            if (common_config('feedsub', 'fallback_hub')) {
+                // No native hub on this feed?
+                // Use our fallback hub, which handles polling on our behalf.
+            } else if (common_config('feedsub', 'nohub')) {
                 // Fake it! We're just testing remote feeds w/o hubs.
+                // We'll never actually get updates in this mode.
                 return true;
             } else {
                 throw new ServerException("Attempting to end PuSH subscription for feed with no hub");
@@ -326,7 +334,21 @@ class FeedSub extends Memcached_DataObject
                           'hub.secret' => $this->secret,
                           'hub.topic' => $this->uri);
             $client = new HTTPClient();
-            $response = $client->post($this->huburi, $headers, $post);
+            if ($this->huburi) {
+                $hub = $this->huburi;
+            } else {
+                if (common_config('feedsub', 'fallback_hub')) {
+                    $hub = common_config('feedsub', 'fallback_hub');
+                    if (common_config('feedsub', 'hub_user')) {
+                        $u = common_config('feedsub', 'hub_user');
+                        $p = common_config('feedsub', 'hub_pass');
+                        $client->setAuth($u, $p);
+                    }
+                } else {
+                    throw new FeedSubException('WTF?');
+                }
+            }
+            $response = $client->post($hub, $headers, $post);
             $status = $response->getStatus();
             if ($status == 202) {
                 common_log(LOG_INFO, __METHOD__ . ': sub req ok, awaiting verification callback');
index 2d7c632e6391151bd46dda8923ce96ea6b4ff7d6..77a5e22cc02a2248b743def14da12b47c13bccf6 100644 (file)
@@ -493,8 +493,14 @@ class Ostatus_profile extends Memcached_DataObject
                 // OK here! assume the default
             } else if ($actor->id == $this->uri || $actor->link == $this->uri) {
                 $this->updateFromActivityObject($actor);
-            } else {
+            } else if ($actor->id) {
+                // We have an ActivityStreams actor with an explicit ID that doesn't match the feed owner.
+                // This isn't what we expect from mainline OStatus person feeds!
+                // Group feeds go down another path, with different validation.
                 throw new Exception("Got an actor '{$actor->title}' ({$actor->id}) on single-user feed for {$this->uri}");
+            } else {
+                // Plain <author> without ActivityStreams actor info.
+                // We'll just ignore this info for now and save the update under the feed's identity.
             }
 
             $oprofile = $this;
@@ -869,12 +875,12 @@ class Ostatus_profile extends Memcached_DataObject
         $feeduri = $discover->discoverFromFeedURL($feed_url);
         $hints['feedurl'] = $feeduri;
 
-        $huburi = $discover->getAtomLink('hub');
+        $huburi = $discover->getHubLink();
         $hints['hub'] = $huburi;
         $salmonuri = $discover->getAtomLink(Salmon::NS_REPLIES);
         $hints['salmon'] = $salmonuri;
 
-        if (!$huburi) {
+        if (!$huburi && !common_config('feedsub', 'fallback_hub')) {
             // We can only deal with folks with a PuSH hub
             throw new FeedSubNoHubException();
         }
@@ -1270,10 +1276,10 @@ class Ostatus_profile extends Memcached_DataObject
                 $discover = new FeedDiscovery();
                 $discover->discoverFromFeedURL($hints['feedurl']);
             }
-            $huburi = $discover->getAtomLink('hub');
+            $huburi = $discover->getHubLink();
         }
 
-        if (!$huburi) {
+        if (!$huburi && !common_config('feedsub', 'fallback_hub')) {
             // We can only deal with folks with a PuSH hub
             throw new FeedSubNoHubException();
         }
index 4ac243832617b89b00737b3e497f9ed27dc662a4..a55399d7c8e9ef29cfa45bd83e4a15b6866859d9 100644 (file)
@@ -87,6 +87,16 @@ class FeedDiscovery
         return ActivityUtils::getLink($this->root, $rel, $type);
     }
 
+    /**
+     * Get the referenced PuSH hub link from an Atom feed.
+     *
+     * @return mixed string or false
+     */
+    public function getHubLink()
+    {
+        return $this->getAtomLink('hub');
+    }
+
     /**
      * @param string $url
      * @param bool $htmlOk pass false here if you don't want to follow web pages.
index d06de4f9030d7cfc53f785ce6d6804cc1a984884..64afa0f3568821849bc505ed8d8a79872e2b518b 100644 (file)
@@ -55,7 +55,7 @@ print "Re-running feed discovery for profile URL $oprofile->uri\n";
 // @fixme will bork where the URI isn't the profile URL for now
 $discover = new FeedDiscovery();
 $feedurl = $discover->discoverFromURL($oprofile->uri);
-$huburi = $discover->getAtomLink('hub');
+$huburi = $discover->getHubLink();
 $salmonuri = $discover->getAtomLink(Salmon::NS_REPLIES);
 
 print "  Feed URL: $feedurl\n";