summaryrefslogtreecommitdiff
path: root/plugins/OStatus
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/OStatus')
-rw-r--r--plugins/OStatus/OStatusPlugin.php4
-rw-r--r--plugins/OStatus/actions/ostatussub.php2
-rw-r--r--plugins/OStatus/classes/Ostatus_profile.php50
-rw-r--r--plugins/OStatus/extlib/hkit/hkit.class.php2
-rw-r--r--plugins/OStatus/lib/discoveryhints.php108
-rw-r--r--plugins/OStatus/lib/linkheader.php24
-rw-r--r--plugins/OStatus/scripts/updateostatus.php14
7 files changed, 104 insertions, 100 deletions
diff --git a/plugins/OStatus/OStatusPlugin.php b/plugins/OStatus/OStatusPlugin.php
index b472ae242..58f373e45 100644
--- a/plugins/OStatus/OStatusPlugin.php
+++ b/plugins/OStatus/OStatusPlugin.php
@@ -290,7 +290,7 @@ class OStatusPlugin extends Plugin
$url = "$scheme://$target";
$this->log(LOG_INFO, "Checking profile address '$url'");
try {
- $oprofile = Ostatus_profile::ensureProfile($url);
+ $oprofile = Ostatus_profile::ensureProfileURL($url);
if ($oprofile && !$oprofile->isGroup()) {
$profile = $oprofile->localProfile();
$matches[$pos] = array('mentioned' => array($profile),
@@ -392,7 +392,7 @@ class OStatusPlugin extends Plugin
foreach ($urls as $url) {
try {
- return Ostatus_profile::ensureProfile($url);
+ return Ostatus_profile::ensureProfileURL($url);
} catch (Exception $e) {
common_log(LOG_ERR, 'Profile lookup failed for ' .
$arg . ': ' . $e->getMessage());
diff --git a/plugins/OStatus/actions/ostatussub.php b/plugins/OStatus/actions/ostatussub.php
index 07081c2c6..994af6e95 100644
--- a/plugins/OStatus/actions/ostatussub.php
+++ b/plugins/OStatus/actions/ostatussub.php
@@ -299,7 +299,7 @@ class OStatusSubAction extends Action
if ($user->isSubscribed($local)) {
// TRANS: OStatus remote subscription dialog error.
$this->showForm(_m('Already subscribed!'));
- } elseif ($this->oprofile->subscribeLocalToRemote($user)) {
+ } elseif (Subscription::start($user, $local)) {
$this->success();
} else {
// TRANS: OStatus remote subscription dialog error.
diff --git a/plugins/OStatus/classes/Ostatus_profile.php b/plugins/OStatus/classes/Ostatus_profile.php
index e47b6973d..95c002b01 100644
--- a/plugins/OStatus/classes/Ostatus_profile.php
+++ b/plugins/OStatus/classes/Ostatus_profile.php
@@ -195,52 +195,6 @@ class Ostatus_profile extends Memcached_DataObject
}
/**
- * Subscribe a local user to this remote user.
- * PuSH subscription will be started if necessary, and we'll
- * send a Salmon notification to the remote server if available
- * notifying them of the sub.
- *
- * @param User $user
- * @return boolean success
- * @throws FeedException
- */
- public function subscribeLocalToRemote(User $user)
- {
- if ($this->isGroup()) {
- throw new ServerException("Can't subscribe to a remote group");
- }
-
- if ($this->subscribe()) {
- if ($user->subscribeTo($this->localProfile())) {
- $this->notify($user->getProfile(), ActivityVerb::FOLLOW, $this);
- return true;
- }
- }
- return false;
- }
-
- /**
- * Mark this remote profile as subscribing to the given local user,
- * and send appropriate notifications to the user.
- *
- * This will generally be in response to a subscription notification
- * from a foreign site to our local Salmon response channel.
- *
- * @param User $user
- * @return boolean success
- */
- public function subscribeRemoteToLocal(User $user)
- {
- if ($this->isGroup()) {
- throw new ServerException("Remote groups can't subscribe to local users");
- }
-
- Subscription::start($this->localProfile(), $user->getProfile());
-
- return true;
- }
-
- /**
* Send a subscription request to the hub for this feed.
* The hub will later send us a confirmation POST to /main/push/callback.
*
@@ -1457,7 +1411,7 @@ class Ostatus_profile extends Memcached_DataObject
if (array_key_exists('feedurl', $hints)) {
try {
- common_log(LOG_INFO, "Discovery on acct:$addr with feed URL $feedUrl");
+ common_log(LOG_INFO, "Discovery on acct:$addr with feed URL " . $hints['feedurl']);
$oprofile = self::ensureFeedURL($hints['feedurl'], $hints);
self::cacheSet(sprintf('ostatus_profile:webfinger:%s', $addr), $oprofile->uri);
return $oprofile;
@@ -1472,7 +1426,7 @@ class Ostatus_profile extends Memcached_DataObject
if (array_key_exists('profileurl', $hints)) {
try {
common_log(LOG_INFO, "Discovery on acct:$addr with profile URL $profileUrl");
- $oprofile = self::ensureProfile($hints['profileurl'], $hints);
+ $oprofile = self::ensureProfileURL($hints['profileurl'], $hints);
self::cacheSet(sprintf('ostatus_profile:webfinger:%s', $addr), $oprofile->uri);
return $oprofile;
} catch (Exception $e) {
diff --git a/plugins/OStatus/extlib/hkit/hkit.class.php b/plugins/OStatus/extlib/hkit/hkit.class.php
index c3a54cff6..fec6f4d8f 100644
--- a/plugins/OStatus/extlib/hkit/hkit.class.php
+++ b/plugins/OStatus/extlib/hkit/hkit.class.php
@@ -472,4 +472,4 @@
}
-?> \ No newline at end of file
+?>
diff --git a/plugins/OStatus/lib/discoveryhints.php b/plugins/OStatus/lib/discoveryhints.php
index db13793dd..0273b5a92 100644
--- a/plugins/OStatus/lib/discoveryhints.php
+++ b/plugins/OStatus/lib/discoveryhints.php
@@ -65,17 +65,22 @@ class DiscoveryHints {
{
common_debug("starting tidy");
- $body = self::_tidy($body);
+ $body = self::_tidy($body, $url);
common_debug("done with tidy");
set_include_path(get_include_path() . PATH_SEPARATOR . INSTALLDIR . '/plugins/OStatus/extlib/hkit/');
require_once('hkit.class.php');
- $h = new hKit;
+ // hKit code is not clean for notices and warnings
+ $old = error_reporting();
+ error_reporting($old & ~E_NOTICE & ~E_WARNING);
+ $h = new hKit;
$hcards = $h->getByString('hcard', $body);
+ error_reporting($old);
+
if (empty($hcards)) {
return array();
}
@@ -144,39 +149,80 @@ class DiscoveryHints {
return $hints;
}
- private static function _tidy($body)
+ /**
+ * hKit needs well-formed XML for its parsing.
+ * We'll take the HTML body here and normalize it to XML.
+ *
+ * @param string $body HTML document source, possibly not-well-formed
+ * @param string $url source URL
+ * @return string well-formed XML document source
+ * @throws Exception if HTML parsing failed.
+ */
+ private static function _tidy($body, $url)
{
- if (function_exists('tidy_parse_string')) {
- common_debug("Tidying with extension");
- $text = tidy_parse_string($body);
- $text = tidy_clean_repair($text);
- return $body;
- } else if ($fullpath = self::_findProgram('tidy')) {
- common_debug("Tidying with program $fullpath");
- $tempfile = tempnam('/tmp', 'snht'); // statusnet hcard tidy
- file_put_contents($tempfile, $source);
- exec("$fullpath -utf8 -indent -asxhtml -numeric -bare -quiet $tempfile", $tidy);
- unlink($tempfile);
- return implode("\n", $tidy);
- } else {
- common_debug("Not tidying.");
- return $body;
+ if (empty($body)) {
+ throw new Exception("Empty HTML could not be parsed.");
}
- }
-
- private static function _findProgram($name)
- {
- $path = $_ENV['PATH'];
-
- $parts = explode(':', $path);
+ $dom = new DOMDocument();
+
+ // Some HTML errors will trigger warnings, but still work.
+ $old = error_reporting();
+ error_reporting($old & ~E_WARNING);
+
+ $ok = $dom->loadHTML($body);
+
+ error_reporting($old);
+
+ if ($ok) {
+ // If the original had xmlns or xml:lang attributes on the
+ // <html>, we seen to end up with duplicates, which causes
+ // parse errors. Remove em!
+ //
+ // For some reason we have to iterate and remove them twice,
+ // *plus* they don't show up on hasAttribute() or removeAttribute().
+ // This might be some weird bug in PHP or libxml2, uncertain if
+ // it affects other folks consistently.
+ $root = $dom->documentElement;
+ foreach ($root->attributes as $i => $x) {
+ if ($i == 'xmlns' || $i == 'xml:lang') {
+ $root->removeAttributeNode($x);
+ }
+ }
+ foreach ($root->attributes as $i => $x) {
+ if ($i == 'xmlns' || $i == 'xml:lang') {
+ $root->removeAttributeNode($x);
+ }
+ }
- foreach ($parts as $part) {
- $fullpath = $part . '/' . $name;
- if (is_executable($fullpath)) {
- return $fullpath;
+ // hKit doesn't give us a chance to pass the source URL for
+ // resolving relative links, such as the avatar photo on a
+ // Google profile. We'll slip it into a <base> tag if there's
+ // not already one present.
+ $bases = $dom->getElementsByTagName('base');
+ if ($bases && $bases->length >= 1) {
+ $base = $bases->item(0);
+ if ($base->hasAttribute('href')) {
+ $base->setAttribute('href', $url);
+ }
+ } else {
+ $base = $dom->createElement('base');
+ $base->setAttribute('href', $url);
+ $heads = $dom->getElementsByTagName('head');
+ if ($heads || $heads->length) {
+ $head = $heads->item(0);
+ } else {
+ $head = $dom->createElement('head');
+ if ($root->firstChild) {
+ $root->insertBefore($head, $root->firstChild);
+ } else {
+ $root->appendChild($head);
+ }
+ }
+ $head->appendChild($base);
}
+ return $dom->saveXML();
+ } else {
+ throw new Exception("Invalid HTML could not be parsed.");
}
-
- return null;
}
}
diff --git a/plugins/OStatus/lib/linkheader.php b/plugins/OStatus/lib/linkheader.php
index 2f6c66dc9..afcd66d26 100644
--- a/plugins/OStatus/lib/linkheader.php
+++ b/plugins/OStatus/lib/linkheader.php
@@ -43,21 +43,21 @@ class LinkHeader
static function getLink($response, $rel=null, $type=null)
{
$headers = $response->getHeader('Link');
+ if ($headers) {
+ // Can get an array or string, so try to simplify the path
+ if (!is_array($headers)) {
+ $headers = array($headers);
+ }
- // Can get an array or string, so try to simplify the path
- if (!is_array($headers)) {
- $headers = array($headers);
- }
-
- foreach ($headers as $header) {
- $lh = new LinkHeader($header);
+ foreach ($headers as $header) {
+ $lh = new LinkHeader($header);
- if ((is_null($rel) || $lh->rel == $rel) &&
- (is_null($type) || $lh->type == $type)) {
- return $lh->href;
+ if ((is_null($rel) || $lh->rel == $rel) &&
+ (is_null($type) || $lh->type == $type)) {
+ return $lh->href;
+ }
}
}
-
return null;
}
-} \ No newline at end of file
+}
diff --git a/plugins/OStatus/scripts/updateostatus.php b/plugins/OStatus/scripts/updateostatus.php
index d553a7d62..622ded56a 100644
--- a/plugins/OStatus/scripts/updateostatus.php
+++ b/plugins/OStatus/scripts/updateostatus.php
@@ -56,7 +56,12 @@ try {
$user = new User();
if ($user->find()) {
while ($user->fetch()) {
- updateOStatus($user);
+ try {
+ updateOStatus($user);
+ } catch (Exception $e) {
+ common_log(LOG_NOTICE, "Couldn't convert OMB subscriptions ".
+ "for {$user->nickname} to OStatus: " . $e->getMessage());
+ }
}
}
} else {
@@ -98,7 +103,7 @@ function updateOStatus($user)
echo "Checking {$rp->nickname}...";
}
- $op = Ostatus_profile::ensureProfile($rp->profileurl);
+ $op = Ostatus_profile::ensureProfileURL($rp->profileurl);
if (empty($op)) {
echo "can't convert.\n";
@@ -107,8 +112,8 @@ function updateOStatus($user)
if (!have_option('q', 'quiet')) {
echo "Converting...";
}
- Subscription::cancel($up, $rp);
Subscription::start($up, $op->localProfile());
+ Subscription::cancel($up, $rp);
if (!have_option('q', 'quiet')) {
echo "done.\n";
}
@@ -118,8 +123,7 @@ function updateOStatus($user)
if (!have_option('q', 'quiet')) {
echo "fail.\n";
}
- continue;
- common_log(LOG_WARNING, "Couldn't convert OMB subscription (" . $up->nickname . ", " . $rp->nickname .
+ common_log(LOG_NOTICE, "Couldn't convert OMB subscription (" . $up->nickname . ", " . $rp->nickname .
") to OStatus: " . $e->getMessage());
continue;
}