diff options
-rw-r--r-- | lib/atomnoticefeed.php | 5 | ||||
-rw-r--r-- | plugins/OStatus/OStatusPlugin.php | 79 | ||||
-rw-r--r-- | plugins/OStatus/actions/webfinger.php | 12 | ||||
-rw-r--r-- | plugins/OStatus/classes/Ostatus_profile.php | 103 | ||||
-rw-r--r-- | plugins/OStatus/lib/webfinger.php | 14 |
5 files changed, 163 insertions, 50 deletions
diff --git a/lib/atomnoticefeed.php b/lib/atomnoticefeed.php index 7653f9154..d2bf2a416 100644 --- a/lib/atomnoticefeed.php +++ b/lib/atomnoticefeed.php @@ -64,6 +64,11 @@ class AtomNoticeFeed extends Atom10Feed 'http://activitystrea.ms/spec/1.0/' ); + $this->addNamespace( + 'poco', + 'http://portablecontacts.net/spec/1.0' + ); + // XXX: What should the uri be? $this->addNamespace( 'ostatus', diff --git a/plugins/OStatus/OStatusPlugin.php b/plugins/OStatus/OStatusPlugin.php index c5a2db3d8..60bb144a8 100644 --- a/plugins/OStatus/OStatusPlugin.php +++ b/plugins/OStatus/OStatusPlugin.php @@ -137,25 +137,6 @@ class OStatusPlugin extends Plugin } /** - * Add the feed settings page to the Connect Settings menu - * - * @param Action &$action The calling page - * - * @return boolean hook return - */ - function onEndConnectSettingsNav(&$action) - { - $action_name = $action->trimmed('action'); - - $action->menuItem(common_local_url('feedsubsettings'), - _m('Feeds'), - _m('Feed subscription options'), - $action_name === 'feedsubsettings'); - - return true; - } - - /** * Automatically load the actions and libraries used by the plugin * * @param Class $cls the class @@ -215,33 +196,16 @@ class OStatusPlugin extends Plugin * @fixme push webfinger lookup & sending to a background queue * @fixme also detect short-form name for remote subscribees where not ambiguous */ + function onEndNoticeSave($notice) { - $count = preg_match_all('/(\w+\.)*\w+@(\w+\.)*\w+(\w+\-\w+)*\.\w+/', $notice->content, $matches); - if ($count) { - foreach ($matches[0] as $webfinger) { + $mentioned = $notice->getReplies(); - // FIXME: look up locally first + foreach ($mentioned as $profile) { - // Check to see if we've got an actual webfinger - $w = new Webfinger; + $oprofile = Ostatus_profile::staticGet('profile_id', $profile->id); - $endpoint_uri = ''; - - $result = $w->lookup($webfinger); - if (empty($result)) { - continue; - } - - foreach ($result->links as $link) { - if ($link['rel'] == 'salmon') { - $endpoint_uri = $link['href']; - } - } - - if (empty($endpoint_uri)) { - continue; - } + if (!empty($oprofile) && !empty($oprofile->salmonuri)) { // FIXME: this needs to go out in a queue handler @@ -249,9 +213,40 @@ class OStatusPlugin extends Plugin $xml .= $notice->asAtomEntry(); $salmon = new Salmon(); - $salmon->post($endpoint_uri, $xml); + $salmon->post($oprofile->salmonuri, $xml); + } + } + } + + /** + * + */ + + function onEndFindMentions($sender, $text, &$mentions) + { + preg_match_all('/(?:^|\s+)@((?:\w+\.)*\w+@(?:\w+\.)*\w+(?:\w+\-\w+)*\.\w+)/', + $text, + $wmatches, + PREG_OFFSET_CAPTURE); + + foreach ($wmatches[1] as $wmatch) { + + $webfinger = $wmatch[0]; + + $oprofile = Ostatus_profile::ensureWebfinger($webfinger); + + if (!empty($oprofile)) { + + $profile = $oprofile->localProfile(); + + $mentions[] = array('mentioned' => array($profile), + 'text' => $wmatch[0], + 'position' => $wmatch[1], + 'url' => $profile->profileurl); } } + + return true; } /** diff --git a/plugins/OStatus/actions/webfinger.php b/plugins/OStatus/actions/webfinger.php index f4dc61b7d..cf60b8069 100644 --- a/plugins/OStatus/actions/webfinger.php +++ b/plugins/OStatus/actions/webfinger.php @@ -37,7 +37,7 @@ class WebfingerAction extends Action return true; } - + function handle() { $acct = Webfinger::normalize($this->uri); @@ -55,16 +55,22 @@ class WebfingerAction extends Action $xrd->subject = $this->uri; $xrd->alias[] = common_profile_url($nick); - $xrd->links[] = array('rel' => 'http://webfinger.net/rel/profile-page', + $xrd->links[] = array('rel' => Webfinger::PROFILEPAGE, 'type' => 'text/html', 'href' => common_profile_url($nick)); + $xrd->links[] = array('rel' => Webfinger::UPDATESFROM, + 'href' => common_local_url('ApiTimelineUser', + array('id' => $this->user->id, + 'format' => 'atom')), + 'type' => 'application/atom+xml'); + $salmon_url = common_local_url('salmon', array('id' => $this->user->id)); $xrd->links[] = array('rel' => 'salmon', 'href' => $salmon_url); - + // TODO - finalize where the redirect should go on the publisher $url = common_local_url('ostatussub') . '?profile={uri}'; $xrd->links[] = array('rel' => 'http://ostatus.org/schema/1.0/subscribe', diff --git a/plugins/OStatus/classes/Ostatus_profile.php b/plugins/OStatus/classes/Ostatus_profile.php index b67e20202..700168c11 100644 --- a/plugins/OStatus/classes/Ostatus_profile.php +++ b/plugins/OStatus/classes/Ostatus_profile.php @@ -845,4 +845,107 @@ class Ostatus_profile extends Memcached_DataObject return null; } } + + public static function ensureWebfinger($addr) + { + // First, look it up + + $oprofile = Ostatus_profile::staticGet('uri', 'acct:'.$addr); + + if (!empty($oprofile)) { + return $oprofile; + } + + // Now, try some discovery + + $wf = new Webfinger(); + + $result = $wf->lookup($addr); + + if (!$result) { + return null; + } + + foreach ($result->links as $link) { + switch ($link['rel']) { + case Webfinger::PROFILEPAGE: + $profileUrl = $link['href']; + break; + case 'salmon': + $salmonEndpoint = $link['href']; + break; + case Webfinger::UPDATESFROM: + $feedUrl = $link['href']; + break; + default: + common_log(LOG_NOTICE, "Don't know what to do with rel = '{$link['rel']}'"); + break; + } + } + + // If we got a feed URL, try that + + if (isset($feedUrl)) { + try { + $oprofile = self::ensureProfile($feedUrl); + return $oprofile; + } catch (Exception $e) { + common_log(LOG_WARNING, "Failed creating profile from feed URL '$feedUrl': " . $e->getMessage()); + // keep looking + } + } + + // If we got a profile page, try that! + + if (isset($profileUrl)) { + try { + $oprofile = self::ensureProfile($profileUrl); + return $oprofile; + } catch (Exception $e) { + common_log(LOG_WARNING, "Failed creating profile from profile URL '$profileUrl': " . $e->getMessage()); + // keep looking + } + } + + // XXX: try hcard + // XXX: try FOAF + + if (isset($salmonEndpoint)) { + + // An account URL, a salmon endpoint, and a dream? Not much to go + // on, but let's give it a try + + $uri = 'acct:'.$addr; + + $profile = new Profile(); + + $profile->nickname = self::nicknameFromUri($uri); + $profile->created = common_sql_now(); + + $profile_id = $profile->insert(); + + if (!$profile_id) { + common_log_db_error($profile, 'INSERT', __FILE__); + throw new Exception("Couldn't save profile for '$addr'"); + } + + $oprofile = new Ostatus_profile(); + + $oprofile->uri = $uri; + $oprofile->salmonuri = $salmonEndpoint; + $oprofile->profile_id = $profile_id; + $oprofile->created = common_sql_now(); + + $result = $oprofile->insert(); + + if (!$result) { + common_log_db_error($oprofile, 'INSERT', __FILE__); + throw new Exception("Couldn't save ostatus_profile for '$addr'"); + } + + return $oprofile; + } + + return null; + } } diff --git a/plugins/OStatus/lib/webfinger.php b/plugins/OStatus/lib/webfinger.php index 417d54904..0386881d1 100644 --- a/plugins/OStatus/lib/webfinger.php +++ b/plugins/OStatus/lib/webfinger.php @@ -32,11 +32,16 @@ define('WEBFINGER_SERVICE_REL_VALUE', 'lrdd'); /** * Implement the webfinger protocol. */ + class Webfinger { + const PROFILEPAGE = 'http://webfinger.net/rel/profile-page'; + const UPDATESFROM = 'http://schemas.google.com/g/2010#updates-from'; + /** * Perform a webfinger lookup given an account. - */ + */ + public function lookup($id) { $id = $this->normalize($id); @@ -46,7 +51,7 @@ class Webfinger if (!$links) { return false; } - + $services = array(); foreach ($links as $link) { if ($link['template']) { @@ -64,7 +69,7 @@ class Webfinger function normalize($id) { if (substr($id, 0, 7) == 'acct://') { - return substr($id, 7); + return substr($id, 7); } else if (substr($id, 0, 5) == 'acct:') { return substr($id, 5); } @@ -86,7 +91,7 @@ class Webfinger if ($result->host != $domain) { return false; } - + $links = array(); foreach ($result->links as $link) { if ($link['rel'] == WEBFINGER_SERVICE_REL_VALUE) { @@ -140,4 +145,3 @@ class Webfinger } } - |