From db9e57f761b6414e974163e7224d7f04ece291d7 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Fri, 19 Mar 2010 15:50:06 -0500 Subject: ensure from an RSS channel --- plugins/OStatus/classes/Ostatus_profile.php | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/OStatus/classes/Ostatus_profile.php b/plugins/OStatus/classes/Ostatus_profile.php index e0e0223b8..80b980aba 100644 --- a/plugins/OStatus/classes/Ostatus_profile.php +++ b/plugins/OStatus/classes/Ostatus_profile.php @@ -788,9 +788,20 @@ class Ostatus_profile extends Memcached_DataObject throw new FeedSubNoHubException(); } - // Try to get a profile from the feed activity:subject + $feedEl = $discover->root; + + if ($feedEl->tagName == 'feed') { + return self::ensureAtomFeed($feedEl, $hints); + } else if ($feedEl->tagName == 'channel') { + return self::ensureRssChannel($feedEl, $hints); + } else { + throw new FeedSubBadXmlException($feeduri); + } + } - $feedEl = $discover->feed->documentElement; + public static function ensureAtomFeed($feedEl, $hints) + { + // Try to get a profile from the feed activity:subject $subject = ActivityUtils::child($feedEl, Activity::SUBJECT, Activity::SPEC); @@ -838,6 +849,17 @@ class Ostatus_profile extends Memcached_DataObject throw new FeedSubException("Can't find enough profile information to make a feed."); } + public static function ensureRssChannel($feedEl, $hints) + { + // @fixme we should check whether this feed has elements + // with different or elements, and... I dunno. + // Do something about that. + + $obj = ActivityObject::fromRssChannel($feedEl); + + return self::ensureActivityObjectProfile($obj, $hints); + } + /** * Download and update given avatar image * -- cgit v1.2.3-54-g00ecf From db0cf50f658a91d0d0a019256e6e85d73b7a3ff6 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Fri, 19 Mar 2010 15:54:16 -0700 Subject: Avoid notices for accessing undefined array indices in hcard processing --- plugins/OStatus/lib/discoveryhints.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/OStatus/lib/discoveryhints.php b/plugins/OStatus/lib/discoveryhints.php index 9102788e6..80cfbbf15 100644 --- a/plugins/OStatus/lib/discoveryhints.php +++ b/plugins/OStatus/lib/discoveryhints.php @@ -102,7 +102,7 @@ class DiscoveryHints { if (array_key_exists('url', $hcard)) { if (is_string($hcard['url'])) { $hints['homepage'] = $hcard['url']; - } else if (is_array($hcard['url'])) { + } else if (is_array($hcard['url']) && !empty($hcard['url'])) { // HACK get the last one; that's how our hcards look $hints['homepage'] = $hcard['url'][count($hcard['url'])-1]; } @@ -231,7 +231,7 @@ class DiscoveryHints { // If it's got a scheme, use it - if ($parts['scheme'] != '') { + if (!empty($parts['scheme'])) { return $rel; } -- cgit v1.2.3-54-g00ecf From 51283a1b34b52b22a17cd87f7b23ce384b7b6303 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 20 Mar 2010 06:44:38 -0500 Subject: try to make a nickname from the user profile url before using the URI --- plugins/OStatus/classes/Ostatus_profile.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/OStatus/classes/Ostatus_profile.php b/plugins/OStatus/classes/Ostatus_profile.php index 80b980aba..31fba009e 100644 --- a/plugins/OStatus/classes/Ostatus_profile.php +++ b/plugins/OStatus/classes/Ostatus_profile.php @@ -1322,9 +1322,19 @@ class Ostatus_profile extends Memcached_DataObject return $hints['nickname']; } - // Try the definitive ID + // Try the profile url (like foo.example.com or example.com/user/foo) - $nickname = self::nicknameFromURI($object->id); + $profileUrl = ($object->link) ? $object->link : $hints['profileurl']; + + if (!empty($profileUrl)) { + $nickname = self::nicknameFromURI($profileUrl); + } + + // Try the URI (may be a tag:, http:, acct:, ... + + if (empty($nickname)) { + $nickname = self::nicknameFromURI($object->id); + } // Try a Webfinger if one was passed (way) down -- cgit v1.2.3-54-g00ecf From f55850878450b27b00bd18b140f2be1357d9713c Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 20 Mar 2010 07:23:13 -0500 Subject: handle RSS as well as Atom in Ostatus push hits --- plugins/OStatus/classes/Ostatus_profile.php | 32 ++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) (limited to 'plugins') diff --git a/plugins/OStatus/classes/Ostatus_profile.php b/plugins/OStatus/classes/Ostatus_profile.php index 4f449a44d..6885bb953 100644 --- a/plugins/OStatus/classes/Ostatus_profile.php +++ b/plugins/OStatus/classes/Ostatus_profile.php @@ -388,11 +388,17 @@ class Ostatus_profile extends Memcached_DataObject { $feed = $doc->documentElement; - if ($feed->localName != 'feed' || $feed->namespaceURI != Activity::ATOM) { - common_log(LOG_ERR, __METHOD__ . ": not an Atom feed, ignoring"); - return; + if ($feed->localName == 'feed' && $feed->namespaceURI == Activity::ATOM) { + $this->processAtomFeed($feed, $source); + } else if ($feed->localName == 'rss') { // @fixme check namespace + $this->processRssFeed($feed, $source); + } else { + throw new Exception("Unknown feed format."); } + } + public function processAtomFeed(DOMElement $feed, $source) + { $entries = $feed->getElementsByTagNameNS(Activity::ATOM, 'entry'); if ($entries->length == 0) { common_log(LOG_ERR, __METHOD__ . ": no entries in feed update, ignoring"); @@ -405,6 +411,26 @@ class Ostatus_profile extends Memcached_DataObject } } + public function processRssFeed(DOMElement $rss, $source) + { + $channels = $rss->getElementsByTagName('channel'); + + if ($channels->length == 0) { + throw new Exception("RSS feed without a channel."); + } else if ($channels->length > 1) { + common_log(LOG_WARNING, __METHOD__ . ": more than one channel in an RSS feed"); + } + + $channel = $channels->item(0); + + $items = $channel->getElementsByTagName('item'); + + for ($i = 0; $i < $items->length; $i++) { + $item = $items->item($i); + $this->processEntry($item, $channel, $source); + } + } + /** * Process a posted entry from this feed source. * -- cgit v1.2.3-54-g00ecf From 25cb9175231f1515c357035c797cb25ec0b01b44 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 20 Mar 2010 08:25:56 -0500 Subject: Allow PuSH posts without author information Superfeedr (sp.?) posts entries without author information. We can assume that this is intended to be by the original author. Re-structured the checks for entries that come in by PuSH so they can either have no author or an empty author, but not a different author. --- plugins/OStatus/classes/Ostatus_profile.php | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'plugins') diff --git a/plugins/OStatus/classes/Ostatus_profile.php b/plugins/OStatus/classes/Ostatus_profile.php index 6885bb953..79e20adbd 100644 --- a/plugins/OStatus/classes/Ostatus_profile.php +++ b/plugins/OStatus/classes/Ostatus_profile.php @@ -468,17 +468,16 @@ class Ostatus_profile extends Memcached_DataObject return false; } } else { - // Individual user feeds may contain only posts from themselves. - // Authorship is validated against the profile URI on upper layers, - // through PuSH setup or Salmon signature checks. - $actorUri = self::getActorProfileURI($activity); - if ($actorUri == $this->uri) { - // Check if profile info has changed and update it - $this->updateFromActivityObject($activity->actor); + $actor = $activity->actor; + + if (empty($actor)) { + // OK here! assume the default + } else if ($actor->id == $this->uri || $actor->link == $this->uri) { + $this->updateFromActivityObject($actor); } else { - common_log(LOG_WARNING, "OStatus: skipping post with bad author: got $actorUri expected $this->uri"); - return false; + throw new Exception("Got an actor '{$actor->title}' ({$actor->id}) on single-user feed for {$this->uri}"); } + $oprofile = $this; } -- cgit v1.2.3-54-g00ecf From 515acb851384ff063cd7e1088d91798e82af8db8 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 20 Mar 2010 09:30:57 -0500 Subject: fall back to summary or title if content not available --- plugins/OStatus/classes/Ostatus_profile.php | 34 ++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 8 deletions(-) (limited to 'plugins') diff --git a/plugins/OStatus/classes/Ostatus_profile.php b/plugins/OStatus/classes/Ostatus_profile.php index 79e20adbd..bc8d37dc6 100644 --- a/plugins/OStatus/classes/Ostatus_profile.php +++ b/plugins/OStatus/classes/Ostatus_profile.php @@ -481,10 +481,14 @@ class Ostatus_profile extends Memcached_DataObject $oprofile = $this; } + // It's not always an ActivityObject::NOTE, but... let's just say it is. + + $note = $activity->object; + // The id URI will be used as a unique identifier for for the notice, // protecting against duplicate saves. It isn't required to be a URL; // tag: URIs for instance are found in Google Buzz feeds. - $sourceUri = $activity->object->id; + $sourceUri = $note->id; $dupe = Notice::staticGet('uri', $sourceUri); if ($dupe) { common_log(LOG_INFO, "OStatus: ignoring duplicate post: $sourceUri"); @@ -493,16 +497,30 @@ class Ostatus_profile extends Memcached_DataObject // We'll also want to save a web link to the original notice, if provided. $sourceUrl = null; - if ($activity->object->link) { - $sourceUrl = $activity->object->link; + if ($note->link) { + $sourceUrl = $note->link; } else if ($activity->link) { $sourceUrl = $activity->link; - } else if (preg_match('!^https?://!', $activity->object->id)) { - $sourceUrl = $activity->object->id; + } else if (preg_match('!^https?://!', $note->id)) { + $sourceUrl = $note->id; + } + + // Use summary as fallback for content + + if (!empty($note->content)) { + $sourceContent = $note->content; + } else if (!empty($note->summary)) { + $sourceContent = $note->summary; + } else if (!empty($note->title)) { + $sourceContent = $note->title; + } else { + // @fixme fetch from $sourceUrl? + throw new ClientException("No content for notice {$sourceUri}"); } // Get (safe!) HTML and text versions of the content - $rendered = $this->purify($activity->object->content); + + $rendered = $this->purify($sourceContent); $content = html_entity_decode(strip_tags($rendered)); $shortened = common_shorten_links($content); @@ -513,8 +531,8 @@ class Ostatus_profile extends Memcached_DataObject $attachment = null; if (Notice::contentTooLong($shortened)) { - $attachment = $this->saveHTMLFile($activity->object->title, $rendered); - $summary = $activity->object->summary; + $attachment = $this->saveHTMLFile($note->title, $rendered); + $summary = html_entity_decode(strip_tags($note->summary)); if (empty($summary)) { $summary = $content; } -- cgit v1.2.3-54-g00ecf From fb2b45c68abbf48dcdfea330163d17ec56f479bc Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 20 Mar 2010 09:46:22 -0500 Subject: use feedEl for discovery --- plugins/OStatus/classes/Ostatus_profile.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/OStatus/classes/Ostatus_profile.php b/plugins/OStatus/classes/Ostatus_profile.php index bc8d37dc6..efb12a2dd 100644 --- a/plugins/OStatus/classes/Ostatus_profile.php +++ b/plugins/OStatus/classes/Ostatus_profile.php @@ -864,7 +864,7 @@ class Ostatus_profile extends Memcached_DataObject // Sheesh. Not a very nice feed! Let's try fingerpoken in the // entries. - $entries = $discover->feed->getElementsByTagNameNS(Activity::ATOM, 'entry'); + $entries = $feedEl->getElementsByTagNameNS(Activity::ATOM, 'entry'); if (!empty($entries) && $entries->length > 0) { -- cgit v1.2.3-54-g00ecf