Merge branch 'testing' of gitorious.org:statusnet/mainline into testing

This commit is contained in:
Brion Vibber 2010-02-21 18:54:06 -08:00
commit d3996996e4
5 changed files with 163 additions and 50 deletions

View File

@ -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',

View File

@ -136,25 +136,6 @@ class OStatusPlugin extends Plugin
return true;
}
/**
* 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
*
@ -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,11 +213,42 @@ 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;
}
/**
* Notify remote server and garbage collect unused feeds on unsubscribe.
* @fixme send these operations to background queues

View File

@ -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',

View File

@ -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;
}
}

View File

@ -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
}
}