From ea9d6f21ecaff6e26ebe30775d1ddcd6d68d0a11 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Sat, 20 Feb 2010 12:46:48 -0800 Subject: OStatus subscription page fixups; works but needs lots of UI loving! - ostatussub via subscribe button now works again (changed to take profile instead of feed, patched up to the new discovery) - added a quickie hack to allow putting your remote profile URI in place of webfinger acct through the remote-sub button (needs to be patched up to do proper discovery via XRDS or a link or something) --- plugins/OStatus/actions/ostatussub.php | 218 +++++++++++++++++++-------------- 1 file changed, 127 insertions(+), 91 deletions(-) (limited to 'plugins/OStatus/actions/ostatussub.php') diff --git a/plugins/OStatus/actions/ostatussub.php b/plugins/OStatus/actions/ostatussub.php index 239122501..524403143 100644 --- a/plugins/OStatus/actions/ostatussub.php +++ b/plugins/OStatus/actions/ostatussub.php @@ -1,7 +1,7 @@ + * @maintainer Brion Vibber */ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } class OStatusSubAction extends Action { + protected $profile_uri; + protected $preview; + protected $munger; + + /** + * Title of the page + * + * @return string Title of the page + */ - protected $feedurl; - function title() { - return _m("OStatus Subscribe"); + return _m('Authorize subscription'); } - function handle($args) - { - if ($this->validateFeed()) { - $this->showForm(); - } - - return true; + /** + * Instructions for use + * + * @return instructions for use + */ + function getInstructions() + { + return _m('You can subscribe to users from other supported sites. Paste their address or profile URI below:'); } - function showForm($err = null) + function showForm($error=null) { - $this->err = $err; + $this->error = $error; $this->showPage(); } + /** + * Content area of the page + * + * Shows a form for associating a remote OStatus account with this + * StatusNet account. + * + * @return void + */ + function showContent() { + // @fixme is this right place? + if ($this->error) { + $this->text($this->error); + } + $user = common_current_user(); $profile = $user->getProfile(); - $fuser = null; - - $flink = Foreign_link::getByUserID($user->id, FEEDSUB_SERVICE); - - if (!empty($flink)) { - $fuser = $flink->getForeignUser(); - } - $this->elementStart('form', array('method' => 'post', - 'id' => 'form_settings_feedsub', + 'id' => 'ostatus_sub', 'class' => 'form_settings', 'action' => - common_local_url('feedsubsettings'))); + common_local_url('ostatussub'))); $this->hidden('token', common_session_token()); @@ -77,17 +91,47 @@ class OStatusSubAction extends Action $this->elementStart('ul', 'form_data'); $this->elementStart('li'); - $this->input('feedurl', _('Feed URL'), $this->feedurl, _('Enter the URL of a PubSubHubbub-enabled feed')); + $this->input('profile', + _m('Address or profile URL'), + $this->profile_uri, + _m('Enter the profile URL of a PubSubHubbub-enabled feed')); $this->elementEnd('li'); $this->elementEnd('ul'); - $this->submit('subscribe', _m('Subscribe')); + if ($this->preview) { + $this->submit('subscribe', _m('Subscribe')); + } else { + $this->submit('validate', _m('Continue')); + } $this->elementEnd('fieldset'); $this->elementEnd('form'); - $this->previewFeed(); + if ($this->preview) { + $this->previewFeed(); + } + } + + function prepare($args) + { + parent::prepare($args); + $this->profile_uri = $this->arg('profile'); + return true; + } + + function handle($args) + { + parent::handle($args); + if ($_SERVER['REQUEST_METHOD'] == 'POST') { + $this->handlePost(); + } else { + if ($this->profile_uri) { + $this->validateAndPreview(); + } else { + $this->showPage(); + } + } } /** @@ -111,14 +155,15 @@ class OStatusSubAction extends Action return; } - if ($this->arg('subscribe')) { + if ($this->arg('validate')) { + $this->validateAndPreview(); + } else if ($this->arg('subscribe')) { $this->saveFeed(); } else { $this->showForm(_('Unexpected form submission.')); } } - /** * Set up and add a feed * @@ -127,100 +172,91 @@ class OStatusSubAction extends Action */ function validateFeed() { - $feedurl = $this->trimmed('feed'); + $profile_uri = trim($this->arg('profile')); - if ($feedurl == '') { - $this->showForm(_m('Empty feed URL!')); + if ($profile_uri == '') { + $this->showForm(_m('Empty remote profile URL!')); return; } - $this->feedurl = $feedurl; + $this->profile_uri = $profile_uri; - // Get the canonical feed URI and check it + // @fixme validate, normalize bla bla try { - $discover = new FeedDiscovery(); - $uri = $discover->discoverFromURL($feedurl); + $oprofile = Ostatus_profile::ensureProfile($this->profile_uri); + $this->oprofile = $oprofile; + return true; } catch (FeedSubBadURLException $e) { - $this->showForm(_m('Invalid URL or could not reach server.')); - return false; + $err = _m('Invalid URL or could not reach server.'); } catch (FeedSubBadResponseException $e) { - $this->showForm(_m('Cannot read feed; server returned error.')); - return false; + $err = _m('Cannot read feed; server returned error.'); } catch (FeedSubEmptyException $e) { - $this->showForm(_m('Cannot read feed; server returned an empty page.')); - return false; + $err = _m('Cannot read feed; server returned an empty page.'); } catch (FeedSubBadHTMLException $e) { - $this->showForm(_m('Bad HTML, could not find feed link.')); - return false; + $err = _m('Bad HTML, could not find feed link.'); } catch (FeedSubNoFeedException $e) { - $this->showForm(_m('Could not find a feed linked from this URL.')); - return false; + $err = _m('Could not find a feed linked from this URL.'); } catch (FeedSubUnrecognizedTypeException $e) { - $this->showForm(_m('Not a recognized feed type.')); - return false; + $err = _m('Not a recognized feed type.'); } catch (FeedSubException $e) { // Any new ones we forgot about - $this->showForm(_m('Bad feed URL.')); - return false; + $err = sprintf(_m('Bad feed URL: %s %s'), get_class($e), $e->getMessage()); } - - $this->munger = $discover->feedMunger(); - $this->profile = $this->munger->ostatusProfile(); - if ($this->profile->huburi == '') { - $this->showForm(_m('Feed is not PuSH-enabled; cannot subscribe.')); - return false; - } - - return true; + $this->showForm($err); + return false; } function saveFeed() { if ($this->validateFeed()) { $this->preview = true; - $this->profile = Ostatus_profile::ensureProfile($this->munger); - // If not already in use, subscribe to updates via the hub - if ($this->profile->sub_start) { - common_log(LOG_INFO, __METHOD__ . ": double the fun! new sub for {$this->profile->feeduri} last subbed {$this->profile->sub_start}"); - } else { - $ok = $this->profile->subscribe(); - common_log(LOG_INFO, __METHOD__ . ": sub was $ok"); - if (!$ok) { - $this->showForm(_m('Feed subscription failed! Bad response from hub.')); - return; - } - } - // And subscribe the current user to the local profile $user = common_current_user(); - $profile = $this->profile->getProfile(); - - if ($user->isSubscribed($profile)) { - $this->showForm(_m('Already subscribed!')); - } elseif ($user->subscribeTo($profile)) { - $this->showForm(_m('Feed subscribed!')); + + if (!$this->oprofile->subscribe()) { + $this->showForm(_m("Failed to set up server-to-server subscription.")); + return; + } + + if ($this->oprofile->isGroup()) { + $group = $this->oprofile->localGroup(); + if ($user->isMember($group)) { + $this->showForm(_m('Already a member!')); + } elseif (Group_member::join($this->profile->group_id, $user->id)) { + $this->showForm(_m('Joined remote group!')); + } else { + $this->showForm(_m('Remote group join failed!')); + } } else { - $this->showForm(_m('Feed subscription failed!')); + $local = $this->oprofile->localProfile(); + if ($user->isSubscribed($local)) { + $this->showForm(_m('Already subscribed!')); + } elseif ($this->oprofile->subscribeLocalToRemote($user)) { + $this->showForm(_m('Remote user subscribed!')); + } else { + $this->showForm(_m('Remote subscription failed!')); + } } } } - - function previewFeed() + function validateAndPreview() { - $profile = $this->munger->ostatusProfile(); - $notice = $this->munger->notice(0, true); // preview - - if ($notice) { - $this->element('b', null, 'Preview of latest post from this feed:'); - - $item = new NoticeList($notice, $this); - $item->show(); - } else { - $this->element('b', null, 'No posts in this feed yet.'); + if ($this->validateFeed()) { + $this->preview = true; + $this->showForm(_m('Previewing feed:')); } } + function previewFeed() + { + $this->text('Profile preview should go here'); + } + function showScripts() + { + parent::showScripts(); + $this->autofocus('feedurl'); + } } -- cgit v1.2.3-54-g00ecf From 727773cdfa8f229babbfe8a620645f2f4db9bbd8 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 21 Feb 2010 11:24:04 -0500 Subject: redirect ostatussub if not logged in --- plugins/OStatus/actions/ostatussub.php | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'plugins/OStatus/actions/ostatussub.php') diff --git a/plugins/OStatus/actions/ostatussub.php b/plugins/OStatus/actions/ostatussub.php index 524403143..bbbd1b7e6 100644 --- a/plugins/OStatus/actions/ostatussub.php +++ b/plugins/OStatus/actions/ostatussub.php @@ -58,7 +58,6 @@ class OStatusSubAction extends Action $this->showPage(); } - /** * Content area of the page * @@ -116,7 +115,18 @@ class OStatusSubAction extends Action function prepare($args) { parent::prepare($args); + + if (!common_logged_in()) { + // XXX: selfURL() didn't work. :< + common_set_returnto($_SERVER['REQUEST_URI']); + if (Event::handle('RedirectToLogin', array($this, null))) { + common_redirect(common_local_url('login'), 303); + } + return false; + } + $this->profile_uri = $this->arg('profile'); + return true; } @@ -173,13 +183,13 @@ class OStatusSubAction extends Action function validateFeed() { $profile_uri = trim($this->arg('profile')); - + if ($profile_uri == '') { $this->showForm(_m('Empty remote profile URL!')); return; } $this->profile_uri = $profile_uri; - + // @fixme validate, normalize bla bla try { $oprofile = Ostatus_profile::ensureProfile($this->profile_uri); -- cgit v1.2.3-54-g00ecf From f54c9b70dbabb70de93fcdd896297adfff5494f4 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Mon, 22 Feb 2010 11:53:34 +0100 Subject: Fixed error/warning message location in OStatus autorize subscription page --- plugins/OStatus/actions/ostatussub.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'plugins/OStatus/actions/ostatussub.php') diff --git a/plugins/OStatus/actions/ostatussub.php b/plugins/OStatus/actions/ostatussub.php index bbbd1b7e6..8cb8e2ae7 100644 --- a/plugins/OStatus/actions/ostatussub.php +++ b/plugins/OStatus/actions/ostatussub.php @@ -58,6 +58,13 @@ class OStatusSubAction extends Action $this->showPage(); } + function showPageNotice() + { + if ($this->error) { + $this->element('p', 'error', $this->error); + } + } + /** * Content area of the page * @@ -69,11 +76,6 @@ class OStatusSubAction extends Action function showContent() { - // @fixme is this right place? - if ($this->error) { - $this->text($this->error); - } - $user = common_current_user(); $profile = $user->getProfile(); @@ -255,7 +257,7 @@ class OStatusSubAction extends Action { if ($this->validateFeed()) { $this->preview = true; - $this->showForm(_m('Previewing feed:')); + $this->showForm(); } } -- cgit v1.2.3-54-g00ecf From 3569493ba7e77a1a9f19bdbbf3f2d5f262ea8484 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Mon, 22 Feb 2010 17:07:48 +0100 Subject: Added link to Subscriptions page to XHR get the ostatus sub form --- plugins/OStatus/OStatusPlugin.php | 17 +++++++++++++++++ plugins/OStatus/actions/ostatussub.php | 19 ++++++++++++++++--- plugins/OStatus/theme/base/css/ostatus.css | 30 ++++++++++++++++++++++++------ 3 files changed, 57 insertions(+), 9 deletions(-) (limited to 'plugins/OStatus/actions/ostatussub.php') diff --git a/plugins/OStatus/OStatusPlugin.php b/plugins/OStatus/OStatusPlugin.php index 3ac2bb87d..0b0317316 100644 --- a/plugins/OStatus/OStatusPlugin.php +++ b/plugins/OStatus/OStatusPlugin.php @@ -497,4 +497,21 @@ class OStatusPlugin extends Plugin } return true; } + + function onStartShowSubscriptionsContent($action) + { + $user = common_current_user(); + if ($user && ($user->id == $action->profile->id)) { + $action->elementStart('div', 'entity_actions'); + $action->elementStart('p', array('id' => 'entity_remote_subscribe', + 'class' => 'entity_subscribe')); + $action->element('a', array('href' => common_local_url('ostatussub'), + 'class' => 'entity_remote_subscribe') + , _m('Subscribe to remote user')); + $action->elementEnd('p'); + $action->elementEnd('div'); + } + + return true; + } } diff --git a/plugins/OStatus/actions/ostatussub.php b/plugins/OStatus/actions/ostatussub.php index 8cb8e2ae7..95dec19af 100644 --- a/plugins/OStatus/actions/ostatussub.php +++ b/plugins/OStatus/actions/ostatussub.php @@ -55,7 +55,20 @@ class OStatusSubAction extends Action function showForm($error=null) { $this->error = $error; - $this->showPage(); + if ($this->boolean('ajax')) { + header('Content-Type: text/xml;charset=utf-8'); + $this->xw->startDocument('1.0', 'UTF-8'); + $this->elementStart('html'); + $this->elementStart('head'); + $this->element('title', null, _m('Subscribe to user')); + $this->elementEnd('head'); + $this->elementStart('body'); + $this->showContent(); + $this->elementEnd('body'); + $this->elementEnd('html'); + } else { + $this->showPage(); + } } function showPageNotice() @@ -81,7 +94,7 @@ class OStatusSubAction extends Action $profile = $user->getProfile(); $this->elementStart('form', array('method' => 'post', - 'id' => 'ostatus_sub', + 'id' => 'form_ostatus_sub', 'class' => 'form_settings', 'action' => common_local_url('ostatussub'))); @@ -141,7 +154,7 @@ class OStatusSubAction extends Action if ($this->profile_uri) { $this->validateAndPreview(); } else { - $this->showPage(); + $this->showForm(); } } } diff --git a/plugins/OStatus/theme/base/css/ostatus.css b/plugins/OStatus/theme/base/css/ostatus.css index 9bc90a731..feeeb47d3 100644 --- a/plugins/OStatus/theme/base/css/ostatus.css +++ b/plugins/OStatus/theme/base/css/ostatus.css @@ -7,24 +7,42 @@ * @link http://status.net/ */ -#form_ostatus_connect.dialogbox { +#form_ostatus_connect.dialogbox, +#form_ostatus_sub.dialogbox { width:70%; background-image:none; } -#form_ostatus_connect.dialogbox .form_data label { +#form_ostatus_sub.dialogbox { +width:65%; +} +#form_ostatus_connect.dialogbox .form_data label, +#form_ostatus_sub.dialogbox .form_data label { width:34%; } -#form_ostatus_connect.dialogbox .form_data input { +#form_ostatus_connect.dialogbox .form_data input, +#form_ostatus_sub.dialogbox .form_data input { width:57%; } -#form_ostatus_connect.dialogbox .form_data .form_guide { +#form_ostatus_connect.dialogbox .form_data .form_guide, +#form_ostatus_sub.dialogbox .form_data .form_guide { margin-left:36%; } -#form_ostatus_connect.dialogbox #ostatus_nickname { +#form_ostatus_connect.dialogbox #ostatus_nickname, +#form_ostatus_sub.dialogbox #ostatus_nickname { display:none; } -#form_ostatus_connect.dialogbox .submit_dialogbox { +#form_ostatus_connect.dialogbox .submit_dialogbox, +#form_ostatus_sub.dialogbox .submit_dialogbox { min-width:96px; } + +#subscriptions #entity_remote_subscribe { +padding:0; +float:right; +} + +#subscriptions .entity_remote_subscribe { +float:right; +} -- cgit v1.2.3-54-g00ecf From 06f155c02df91ae81eb4401c738815ee46b802a6 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Mon, 22 Feb 2010 09:43:27 -0800 Subject: OStatus: initial hookup of remote group membership (notice delivery not yet working quite right) - added a temp config var to disable salmon magic signatures until they're working consistently --- plugins/OStatus/OStatusPlugin.php | 93 ++++++++++++++- plugins/OStatus/actions/groupsalmon.php | 77 ++++++++++++- plugins/OStatus/actions/ostatussub.php | 2 +- plugins/OStatus/classes/Ostatus_profile.php | 169 +++++++++++++++++++++------- plugins/OStatus/lib/activity.php | 6 + plugins/OStatus/lib/salmon.php | 21 +++- plugins/OStatus/lib/salmonaction.php | 23 +++- 7 files changed, 336 insertions(+), 55 deletions(-) (limited to 'plugins/OStatus/actions/ostatussub.php') diff --git a/plugins/OStatus/OStatusPlugin.php b/plugins/OStatus/OStatusPlugin.php index 7c6c0c69f..061ed4bd1 100644 --- a/plugins/OStatus/OStatusPlugin.php +++ b/plugins/OStatus/OStatusPlugin.php @@ -211,7 +211,7 @@ class OStatusPlugin extends Plugin // FIXME: this needs to go out in a queue handler - $xml = ''; + $xml = ''; $xml .= $notice->asAtomEntry(true, true); $salmon = new Salmon(); @@ -402,6 +402,97 @@ class OStatusPlugin extends Plugin return true; } + /** + * When one of our local users tries to join a remote group, + * notify the remote server. If the notification is rejected, + * deny the join. + * + * @param User_group $group + * @param User $user + * + * @return mixed hook return value + */ + + function onStartJoinGroup($group, $user) + { + $oprofile = Ostatus_profile::staticGet('group_id', $group->id); + if ($oprofile) { + $member = Profile::staticGet($user->id); + + $act = new Activity(); + $act->id = TagURI::mint('join:%d:%d:%s', + $member->id, + $group->id, + common_date_iso8601(time())); + + $act->actor = ActivityObject::fromProfile($member); + $act->verb = ActivityVerb::JOIN; + $act->object = $oprofile->asActivityObject(); + + $act->time = time(); + $act->title = _m("Join"); + $act->content = sprintf(_m("%s has joined group %s."), + $member->getBestName(), + $oprofile->getBestName()); + + if ($oprofile->notifyActivity($act)) { + return true; + } else { + throw new ServerException(_m("Failed joining remote group.")); + } + } + } + + /** + * When one of our local users leaves a remote group, notify the remote + * server. + * + * @fixme Might be good to schedule a resend of the leave notification + * if it failed due to a transitory error. We've canceled the local + * membership already anyway, but if the remote server comes back up + * it'll be left with a stray membership record. + * + * @param User_group $group + * @param User $user + * + * @return mixed hook return value + */ + + function onEndLeaveGroup($group, $user) + { + $oprofile = Ostatus_profile::staticGet('group_id', $group->id); + if ($oprofile) { + // Drop the PuSH subscription if there are no other subscribers. + + $members = $group->getMembers(0, 1); + if ($members->N == 0) { + common_log(LOG_INFO, "Unsubscribing from now-unused group feed $oprofile->feeduri"); + $oprofile->unsubscribe(); + } + + + $member = Profile::staticGet($user->id); + + $act = new Activity(); + $act->id = TagURI::mint('leave:%d:%d:%s', + $member->id, + $group->id, + common_date_iso8601(time())); + + $act->actor = ActivityObject::fromProfile($member); + $act->verb = ActivityVerb::LEAVE; + $act->object = $oprofile->asActivityObject(); + + $act->time = time(); + $act->title = _m("Leave"); + $act->content = sprintf(_m("%s has left group %s."), + $member->getBestName(), + $oprofile->getBestName()); + + $oprofile->notifyActivity($act); + } + } + /** * Notify remote users when their notices get favorited. * diff --git a/plugins/OStatus/actions/groupsalmon.php b/plugins/OStatus/actions/groupsalmon.php index 64ae9f3cc..2e4fe9443 100644 --- a/plugins/OStatus/actions/groupsalmon.php +++ b/plugins/OStatus/actions/groupsalmon.php @@ -88,21 +88,96 @@ class GroupsalmonAction extends SalmonAction * Save a subscription relationship for them. */ + /** + * Postel's law: consider a "follow" notification as a "join". + */ function handleFollow() { - $this->handleJoin(); // ??? + $this->handleJoin(); } + /** + * Postel's law: consider an "unfollow" notification as a "leave". + */ function handleUnfollow() { + $this->handleLeave(); } /** * A remote user joined our group. + * @fixme move permission checks and event call into common code, + * currently we're doing the main logic in joingroup action + * and so have to repeat it here. */ function handleJoin() { + $oprofile = $this->ensureProfile(); + if (!$oprofile) { + $this->clientError(_m("Can't read profile to set up group membership.")); + } + if ($oprofile->isGroup()) { + $this->clientError(_m("Groups can't join groups.")); + } + + common_log(LOG_INFO, "Remote profile {$oprofile->uri} joining local group {$this->group->nickname}"); + $profile = $oprofile->localProfile(); + + if ($profile->isMember($this->group)) { + // Already a member; we'll take it silently to aid in resolving + // inconsistencies on the other side. + return true; + } + + if (Group_block::isBlocked($this->group, $profile)) { + $this->clientError(_('You have been blocked from that group by the admin.'), 403); + return false; + } + + try { + // @fixme that event currently passes a user from main UI + // Event should probably move into Group_member::join + // and take a Profile object. + // + //if (Event::handle('StartJoinGroup', array($this->group, $profile))) { + Group_member::join($this->group->id, $profile->id); + //Event::handle('EndJoinGroup', array($this->group, $profile)); + //} + } catch (Exception $e) { + $this->serverError(sprintf(_m('Could not join remote user %1$s to group %2$s.'), + $oprofile->uri, $this->group->nickname)); + } + } + + /** + * A remote user left our group. + */ + + function handleLeave() + { + $oprofile = $this->ensureProfile(); + if (!$oprofile) { + $this->clientError(_m("Can't read profile to cancel group membership.")); + } + if ($oprofile->isGroup()) { + $this->clientError(_m("Groups can't join groups.")); + } + + common_log(LOG_INFO, "Remote profile {$oprofile->uri} leaving local group {$this->group->nickname}"); + $profile = $oprofile->localProfile(); + + try { + // @fixme event needs to be refactored as above + //if (Event::handle('StartLeaveGroup', array($this->group, $profile))) { + Group_member::leave($this->group->id, $profile->id); + //Event::handle('EndLeaveGroup', array($this->group, $profile)); + //} + } catch (Exception $e) { + $this->serverError(sprintf(_m('Could not remove remote user %1$s from group %2$s.'), + $oprofile->uri, $this->group->nickname)); + return; + } } } diff --git a/plugins/OStatus/actions/ostatussub.php b/plugins/OStatus/actions/ostatussub.php index 95dec19af..592ae387e 100644 --- a/plugins/OStatus/actions/ostatussub.php +++ b/plugins/OStatus/actions/ostatussub.php @@ -248,7 +248,7 @@ class OStatusSubAction extends Action $group = $this->oprofile->localGroup(); if ($user->isMember($group)) { $this->showForm(_m('Already a member!')); - } elseif (Group_member::join($this->profile->group_id, $user->id)) { + } elseif (Group_member::join($this->oprofile->group_id, $user->id)) { $this->showForm(_m('Joined remote group!')); } else { $this->showForm(_m('Remote group join failed!')); diff --git a/plugins/OStatus/classes/Ostatus_profile.php b/plugins/OStatus/classes/Ostatus_profile.php index 0e12f8fc6..c0e39add8 100644 --- a/plugins/OStatus/classes/Ostatus_profile.php +++ b/plugins/OStatus/classes/Ostatus_profile.php @@ -137,12 +137,49 @@ class Ostatus_profile extends Memcached_DataObject return null; } + /** + * Returns an ActivityObject describing this remote user or group profile. + * Can then be used to generate Atom chunks. + * + * @return ActivityObject + */ + function asActivityObject() + { + if ($this->isGroup()) { + $object = new ActivityObject(); + $object->type = 'http://activitystrea.ms/schema/1.0/group'; + $object->id = $this->uri; + $self = $this->localGroup(); + + // @fixme put a standard getAvatar() interface on groups too + if ($self->homepage_logo) { + $object->avatar = $self->homepage_logo; + $map = array('png' => 'image/png', + 'jpg' => 'image/jpeg', + 'jpeg' => 'image/jpeg', + 'gif' => 'image/gif'); + $extension = pathinfo(parse_url($avatarHref, PHP_URL_PATH), PATHINFO_EXTENSION); + if (isset($map[$extension])) { + // @fixme this ain't used/saved yet + $object->avatarType = $map[$extension]; + } + } + + $object->link = $this->uri; // @fixme accurate? + return $object; + } else { + return ActivityObject::fromProfile($this->localProfile()); + } + } + /** * Returns an XML string fragment with profile information as an * Activity Streams noun object with the given element type. * * Assumes that 'activity' namespace has been previously defined. * + * @fixme replace with wrappers on asActivityObject when it's got everything. + * * @param string $element one of 'actor', 'subject', 'object', 'target' * @return string */ @@ -202,11 +239,19 @@ class Ostatus_profile extends Memcached_DataObject } /** - * Damn dirty hack! + * @return boolean true if this is a remote group */ function isGroup() { - return (strpos($this->feeduri, '/groups/') !== false); + if ($this->profile_id && !$this->group_id) { + return false; + } else if ($this->group_id && !$this->profile_id) { + return true; + } else if ($this->group_id && $this->profile_id) { + throw new ServerException("Invalid ostatus_profile state: both group and profile IDs set for $this->uri"); + } else { + throw new ServerException("Invalid ostatus_profile state: both group and profile IDs empty for $this->uri"); + } } /** @@ -353,22 +398,24 @@ class Ostatus_profile extends Memcached_DataObject common_log(LOG_INFO, "Posting to Salmon endpoint $this->salmonuri: $xml"); $salmon = new Salmon(); // ? - $salmon->post($this->salmonuri, $xml); + return $salmon->post($this->salmonuri, $xml); } + return false; } public function notifyActivity($activity) { if ($this->salmonuri) { - $xml = $activity->asString(true); + $xml = '' . + $activity->asString(true); $salmon = new Salmon(); // ? - $salmon->post($this->salmonuri, $xml); + return $salmon->post($this->salmonuri, $xml); } - return; + return false; } function getBestName() @@ -597,10 +644,23 @@ class Ostatus_profile extends Memcached_DataObject */ protected function updateAvatar($url) { + if ($this->isGroup()) { + $self = $this->localGroup(); + } else { + $self = $this->localProfile(); + } + if (!$self) { + throw new ServerException(sprintf( + _m("Tried to update avatar for unsaved remote profile %s"), + $this->uri)); + } + // @fixme this should be better encapsulated // ripped from oauthstore.php (for old OMB client) $temp_filename = tempnam(sys_get_temp_dir(), 'listener_avatar'); - copy($url, $temp_filename); + if (!copy($url, $temp_filename)) { + throw new ServerException(sprintf(_m("Unable to fetch avatar from %s"), $url)); + } if ($this->isGroup()) { $id = $this->group_id; @@ -614,13 +674,7 @@ class Ostatus_profile extends Memcached_DataObject null, common_timestamp()); rename($temp_filename, Avatar::path($filename)); - if ($this->isGroup()) { - $group = $this->localGroup(); - $group->setOriginal($filename); - } else { - $profile = $this->localProfile(); - $profile->setOriginal($filename); - } + $self->setOriginal($filename); } protected static function getActivityObjectAvatar($object) @@ -747,6 +801,18 @@ class Ostatus_profile extends Memcached_DataObject self::createActivityObjectProfile($actor, $feeduri, $salmonuri); } + /** + * Create local ostatus_profile and profile/user_group entries for + * the provided remote user or group. + * + * @param ActivityObject $object + * @param string $feeduri + * @param string $salmonuri + * @param array $hints + * + * @fixme fold $feeduri/$salmonuri into $hints + * @return Ostatus_profile + */ protected static function createActivityObjectProfile($object, $feeduri=null, $salmonuri=null, $hints=array()) { $homeuri = $object->id; @@ -784,46 +850,65 @@ class Ostatus_profile extends Memcached_DataObject } } - $profile = new Profile(); - $profile->nickname = $nickname; - $profile->fullname = $object->title; - if (!empty($object->link)) { - $profile->profileurl = $object->link; - } else if (array_key_exists('profileurl', $hints)) { - $profile->profileurl = $hints['profileurl']; - } - $profile->created = common_sql_now(); - - // @fixme bio - // @fixme tags/categories - // @fixme location? - // @todo tags from categories - // @todo lat/lon/location? - - $profile_id = $profile->insert(); - - if (!$profile_id) { - throw new ServerException("Can't save local profile"); - } - - // @fixme either need to do feed discovery here - // or need to split out some of the feed stuff - // so we can leave it empty until later. - $oprofile = new Ostatus_profile(); $oprofile->uri = $homeuri; $oprofile->feeduri = $feeduri; $oprofile->salmonuri = $salmonuri; - $oprofile->profile_id = $profile_id; $oprofile->created = common_sql_now(); $oprofile->modified = common_sql_now(); + if ($object->type == ActivityObject::PERSON) { + $profile = new Profile(); + $profile->nickname = $nickname; + $profile->fullname = $object->title; + if (!empty($object->link)) { + $profile->profileurl = $object->link; + } else if (array_key_exists('profileurl', $hints)) { + $profile->profileurl = $hints['profileurl']; + } + $profile->created = common_sql_now(); + + // @fixme bio + // @fixme tags/categories + // @fixme location? + // @todo tags from categories + // @todo lat/lon/location? + + $oprofile->profile_id = $profile->insert(); + + if (!$oprofile->profile_id) { + throw new ServerException("Can't save local profile"); + } + } else { + $group = new User_group(); + $group->nickname = $nickname; + $group->fullname = $object->title; + // @fixme no canonical profileurl; using homepage instead for now + $group->homepage = $homeuri; + $group->created = common_sql_now(); + + // @fixme homepage + // @fixme bio + // @fixme tags/categories + // @fixme location? + // @todo tags from categories + // @todo lat/lon/location? + + $oprofile->group_id = $group->insert(); + + if (!$oprofile->group_id) { + throw new ServerException("Can't save local profile"); + } + } + $ok = $oprofile->insert(); if ($ok) { - $oprofile->updateAvatar($avatar); + if ($avatar) { + $oprofile->updateAvatar($avatar); + } return $oprofile; } else { throw new ServerException("Can't save OStatus profile"); diff --git a/plugins/OStatus/lib/activity.php b/plugins/OStatus/lib/activity.php index a26248f19..6cb9881bf 100644 --- a/plugins/OStatus/lib/activity.php +++ b/plugins/OStatus/lib/activity.php @@ -367,6 +367,9 @@ class ActivityObject return $object; } + /** + * @fixme missing avatar, bio info, etc + */ static function fromProfile($profile) { $object = new ActivityObject(); @@ -379,6 +382,9 @@ class ActivityObject return $object; } + /** + * @fixme missing avatar, bio info, etc + */ function asString($tag='activity:object') { $xs = new XMLStringer(true); diff --git a/plugins/OStatus/lib/salmon.php b/plugins/OStatus/lib/salmon.php index 53925dc3f..b5f178cc6 100644 --- a/plugins/OStatus/lib/salmon.php +++ b/plugins/OStatus/lib/salmon.php @@ -28,15 +28,26 @@ */ class Salmon { + /** + * Sign and post the given Atom entry as a Salmon message. + * + * @fixme pass through the actor for signing? + * + * @param string $endpoint_uri + * @param string $xml + * @return boolean success + */ public function post($endpoint_uri, $xml) { if (empty($endpoint_uri)) { - return FALSE; + return false; } - $xml = $this->createMagicEnv($xml); - - $headers = array('Content-type: application/atom+xml'); + if (!common_config('ostatus', 'skip_signatures')) { + $xml = $this->createMagicEnv($xml); + } + + $headers = array('Content-Type: application/atom+xml'); try { $client = new HTTPClient(); @@ -51,7 +62,7 @@ class Salmon $response->getStatus() . ': ' . $response->getBody()); return false; } - + return true; } public function createMagicEnv($text) diff --git a/plugins/OStatus/lib/salmonaction.php b/plugins/OStatus/lib/salmonaction.php index 09a042975..83cf0b8f8 100644 --- a/plugins/OStatus/lib/salmonaction.php +++ b/plugins/OStatus/lib/salmonaction.php @@ -41,7 +41,7 @@ class SalmonAction extends Action $this->clientError(_('This method requires a POST.')); } - if ($_SERVER['CONTENT_TYPE'] != 'application/atom+xml') { + if (empty($_SERVER['CONTENT_TYPE']) || $_SERVER['CONTENT_TYPE'] != 'application/atom+xml') { $this->clientError(_('Salmon requires application/atom+xml')); } @@ -57,11 +57,13 @@ class SalmonAction extends Action // Check the signature $salmon = new Salmon; - if (!$salmon->verifyMagicEnv($dom)) { - common_log(LOG_DEBUG, "Salmon signature verification failed."); - $this->clientError(_m('Salmon signature verification failed.')); + if (!common_config('ostatus', 'skip_signatures')) { + if (!$salmon->verifyMagicEnv($dom)) { + common_log(LOG_DEBUG, "Salmon signature verification failed."); + $this->clientError(_m('Salmon signature verification failed.')); + } } - + $this->act = new Activity($dom->documentElement); return true; } @@ -101,6 +103,9 @@ class SalmonAction extends Action case ActivityVerb::JOIN: $this->handleJoin(); break; + case ActivityVerb::LEAVE: + $this->handleLeave(); + break; default: throw new ClientException(_("Unimplemented.")); } @@ -154,6 +159,14 @@ class SalmonAction extends Action throw new ClientException(_("Unimplemented!")); } + /** + * Hmmmm + */ + function handleLeave() + { + throw new ClientException(_("Unimplemented!")); + } + /** * @return Ostatus_profile */ -- cgit v1.2.3-54-g00ecf From 193448d1be53e27232477bed4d3fa7c2c6f39fbf Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Tue, 23 Feb 2010 01:58:05 +0000 Subject: OStatus: cleanup on ostatussub preparing for final UI work on the remote sub/join forms. --- plugins/OStatus/actions/ostatussub.php | 387 ++++++++++++++++++++------------- 1 file changed, 237 insertions(+), 150 deletions(-) (limited to 'plugins/OStatus/actions/ostatussub.php') diff --git a/plugins/OStatus/actions/ostatussub.php b/plugins/OStatus/actions/ostatussub.php index 592ae387e..ffa88cb08 100644 --- a/plugins/OStatus/actions/ostatussub.php +++ b/plugins/OStatus/actions/ostatussub.php @@ -24,70 +24,29 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } +/** + * Key UI methods: + * + * showInputForm() - form asking for a remote profile account or URL + * We end up back here on errors + * + * showPreviewForm() - surrounding form for preview-and-confirm + * previewUser() - display profile for a remote user + * previewGroup() - display profile for a remote group + * + * successUser() - redirects to subscriptions page on subscribe + * successGroup() - redirects to groups page on join + */ class OStatusSubAction extends Action { - protected $profile_uri; - protected $preview; - protected $munger; + protected $profile_uri; // provided acct: or URI of remote entity + protected $oprofile; // Ostatus_profile of remote entity, if valid /** - * Title of the page - * - * @return string Title of the page + * Show the initial form, when we haven't yet been given a valid + * remote profile. */ - - function title() - { - return _m('Authorize subscription'); - } - - /** - * Instructions for use - * - * @return instructions for use - */ - - function getInstructions() - { - return _m('You can subscribe to users from other supported sites. Paste their address or profile URI below:'); - } - - function showForm($error=null) - { - $this->error = $error; - if ($this->boolean('ajax')) { - header('Content-Type: text/xml;charset=utf-8'); - $this->xw->startDocument('1.0', 'UTF-8'); - $this->elementStart('html'); - $this->elementStart('head'); - $this->element('title', null, _m('Subscribe to user')); - $this->elementEnd('head'); - $this->elementStart('body'); - $this->showContent(); - $this->elementEnd('body'); - $this->elementEnd('html'); - } else { - $this->showPage(); - } - } - - function showPageNotice() - { - if ($this->error) { - $this->element('p', 'error', $this->error); - } - } - - /** - * Content area of the page - * - * Shows a form for associating a remote OStatus account with this - * StatusNet account. - * - * @return void - */ - - function showContent() + function showInputForm() { $user = common_current_user(); @@ -112,18 +71,167 @@ class OStatusSubAction extends Action $this->elementEnd('li'); $this->elementEnd('ul'); - if ($this->preview) { - $this->submit('subscribe', _m('Subscribe')); + $this->submit('validate', _m('Continue')); + + $this->elementEnd('fieldset'); + + $this->elementEnd('form'); + } + + /** + * Show the preview-and-confirm form. We've got a valid remote + * profile and are ready to poke it! + * + * This controls the wrapper form; actual profile display will + * be in previewUser() or previewGroup() depending on the type. + */ + function showPreviewForm() + { + $this->elementStart('form', array('method' => 'post', + 'id' => 'form_ostatus_sub', + 'class' => 'form_settings', + 'action' => + common_local_url('ostatussub'))); + + $this->hidden('token', common_session_token()); + $this->hidden('profile', $this->profile_uri); + + $this->elementStart('fieldset', array('id' => 'settings_feeds')); + + if ($this->oprofile->isGroup()) { + $this->previewGroup(); + $this->submit('subscribe', _m('Join')); } else { - $this->submit('validate', _m('Continue')); + $this->previewUser(); + $this->submit('subscribe', _m('Subscribe')); } + $this->elementEnd('fieldset'); $this->elementEnd('form'); + } + + /** + * Show a preview for a remote user's profile + */ + function previewUser() + { + $oprofile = $this->oprofile; + $profile = $oprofile->localProfile(); + + $this->text(sprintf(_m("Remote user %s"), $profile->nickname)); + // ... + } + + /** + * Show a preview for a remote group's profile + */ + function previewGroup() + { + $oprofile = $this->oprofile; + $group = $oprofile->localGroup(); + + $this->text(sprintf(_m("Remote group %s"), $group->nickname)); + // .. + } + + /** + * Redirect on successful remote user subscription + */ + function successUser() + { + $cur = common_current_user(); + $url = common_local_url('subscriptions', array('nickname' => $cur->nickname)); + common_redirect($url, 303); + } + + /** + * Redirect on successful remote group join + */ + function successGroup() + { + $cur = common_current_user(); + $url = common_local_url('usergroups', array('nickname' => $cur->nickname)); + common_redirect($url, 303); + } + + /** + * Pull data for a remote profile and check if it's valid. + * Fills out error UI string in $this->error + * Fills out $this->oprofile on success. + * + * @return boolean + */ + function validateFeed() + { + $profile_uri = trim($this->arg('profile')); - if ($this->preview) { - $this->previewFeed(); + if ($profile_uri == '') { + $this->showForm(_m('Empty remote profile URL!')); + return; + } + $this->profile_uri = $profile_uri; + + // @fixme validate, normalize bla bla + try { + $oprofile = Ostatus_profile::ensureProfile($this->profile_uri); + $this->oprofile = $oprofile; + return true; + } catch (FeedSubBadURLException $e) { + $this->error = _m('Invalid URL or could not reach server.'); + } catch (FeedSubBadResponseException $e) { + $this->error = _m('Cannot read feed; server returned error.'); + } catch (FeedSubEmptyException $e) { + $this->error = _m('Cannot read feed; server returned an empty page.'); + } catch (FeedSubBadHTMLException $e) { + $this->error = _m('Bad HTML, could not find feed link.'); + } catch (FeedSubNoFeedException $e) { + $this->error = _m('Could not find a feed linked from this URL.'); + } catch (FeedSubUnrecognizedTypeException $e) { + $this->error = _m('Not a recognized feed type.'); + } catch (FeedSubException $e) { + // Any new ones we forgot about + $this->error = sprintf(_m('Bad feed URL: %s %s'), get_class($e), $e->getMessage()); + } + + return false; + } + + /** + * Attempt to finalize subscription. + * validateFeed must have been run first. + * + * Calls showForm on failure or successUser/successGroup on success. + */ + function saveFeed() + { + // And subscribe the current user to the local profile + $user = common_current_user(); + + if (!$this->oprofile->subscribe()) { + $this->showForm(_m("Failed to set up server-to-server subscription.")); + return; + } + + if ($this->oprofile->isGroup()) { + $group = $this->oprofile->localGroup(); + if ($user->isMember($group)) { + $this->showForm(_m('Already a member!')); + } elseif (Group_member::join($this->oprofile->group_id, $user->id)) { + $this->successGroup(); + } else { + $this->showForm(_m('Remote group join failed!')); + } + } else { + $local = $this->oprofile->localProfile(); + if ($user->isSubscribed($local)) { + $this->showForm(_m('Already subscribed!')); + } elseif ($this->oprofile->subscribeLocalToRemote($user)) { + $this->successUser(); + } else { + $this->showForm(_m('Remote subscription failed!')); + } } } @@ -145,28 +253,26 @@ class OStatusSubAction extends Action return true; } + /** + * Handle the submission. + */ function handle($args) { parent::handle($args); if ($_SERVER['REQUEST_METHOD'] == 'POST') { $this->handlePost(); } else { - if ($this->profile_uri) { - $this->validateAndPreview(); - } else { - $this->showForm(); + if ($this->arg('profile')) { + $this->validateFeed(); } + $this->showForm(); } } + /** * Handle posts to this form * - * Based on the button that was pressed, muxes out to other functions - * to do the actual task requested. - * - * All sub-functions reload the form with a message -- success or failure. - * * @return void */ @@ -180,103 +286,84 @@ class OStatusSubAction extends Action return; } - if ($this->arg('validate')) { - $this->validateAndPreview(); - } else if ($this->arg('subscribe')) { - $this->saveFeed(); - } else { - $this->showForm(_('Unexpected form submission.')); + if ($this->validateFeed()) { + if ($this->arg('subscribe')) { + $this->saveFeed(); + return; + } } + $this->showForm(); } /** - * Set up and add a feed - * - * @return boolean true if feed successfully read - * Sends you back to input form if not. + * Show the appropriate form based on our input state. */ - function validateFeed() + function showForm($err=null) { - $profile_uri = trim($this->arg('profile')); - - if ($profile_uri == '') { - $this->showForm(_m('Empty remote profile URL!')); - return; + if ($err) { + $this->error = $err; } - $this->profile_uri = $profile_uri; - - // @fixme validate, normalize bla bla - try { - $oprofile = Ostatus_profile::ensureProfile($this->profile_uri); - $this->oprofile = $oprofile; - return true; - } catch (FeedSubBadURLException $e) { - $err = _m('Invalid URL or could not reach server.'); - } catch (FeedSubBadResponseException $e) { - $err = _m('Cannot read feed; server returned error.'); - } catch (FeedSubEmptyException $e) { - $err = _m('Cannot read feed; server returned an empty page.'); - } catch (FeedSubBadHTMLException $e) { - $err = _m('Bad HTML, could not find feed link.'); - } catch (FeedSubNoFeedException $e) { - $err = _m('Could not find a feed linked from this URL.'); - } catch (FeedSubUnrecognizedTypeException $e) { - $err = _m('Not a recognized feed type.'); - } catch (FeedSubException $e) { - // Any new ones we forgot about - $err = sprintf(_m('Bad feed URL: %s %s'), get_class($e), $e->getMessage()); + if ($this->boolean('ajax')) { + header('Content-Type: text/xml;charset=utf-8'); + $this->xw->startDocument('1.0', 'UTF-8'); + $this->elementStart('html'); + $this->elementStart('head'); + $this->element('title', null, _m('Subscribe to user')); + $this->elementEnd('head'); + $this->elementStart('body'); + $this->showContent(); + $this->elementEnd('body'); + $this->elementEnd('html'); + } else { + $this->showPage(); } - - $this->showForm($err); - return false; } - function saveFeed() - { - if ($this->validateFeed()) { - $this->preview = true; + /** + * Title of the page + * + * @return string Title of the page + */ - // And subscribe the current user to the local profile - $user = common_current_user(); + function title() + { + return _m('Authorize subscription'); + } - if (!$this->oprofile->subscribe()) { - $this->showForm(_m("Failed to set up server-to-server subscription.")); - return; - } + /** + * Instructions for use + * + * @return instructions for use + */ - if ($this->oprofile->isGroup()) { - $group = $this->oprofile->localGroup(); - if ($user->isMember($group)) { - $this->showForm(_m('Already a member!')); - } elseif (Group_member::join($this->oprofile->group_id, $user->id)) { - $this->showForm(_m('Joined remote group!')); - } else { - $this->showForm(_m('Remote group join failed!')); - } - } else { - $local = $this->oprofile->localProfile(); - if ($user->isSubscribed($local)) { - $this->showForm(_m('Already subscribed!')); - } elseif ($this->oprofile->subscribeLocalToRemote($user)) { - $this->showForm(_m('Remote user subscribed!')); - } else { - $this->showForm(_m('Remote subscription failed!')); - } - } - } + function getInstructions() + { + return _m('You can subscribe to users from other supported sites. Paste their address or profile URI below:'); } - function validateAndPreview() + function showPageNotice() { - if ($this->validateFeed()) { - $this->preview = true; - $this->showForm(); + if ($this->error) { + $this->element('p', 'error', $this->error); } } - function previewFeed() + /** + * Content area of the page + * + * Shows a form for associating a remote OStatus account with this + * StatusNet account. + * + * @return void + */ + + function showContent() { - $this->text('Profile preview should go here'); + if ($this->oprofile) { + $this->showPreviewForm(); + } else { + $this->showInputForm(); + } } function showScripts() -- cgit v1.2.3-54-g00ecf From b67bb182b008b5f7b66d39df7bb8dab449b7002a Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Tue, 23 Feb 2010 04:59:34 +0100 Subject: Refactored preview info and form for authorizing a remote subscription --- plugins/OStatus/actions/ostatussub.php | 113 ++++++++++++++++++++++++++++----- 1 file changed, 97 insertions(+), 16 deletions(-) (limited to 'plugins/OStatus/actions/ostatussub.php') diff --git a/plugins/OStatus/actions/ostatussub.php b/plugins/OStatus/actions/ostatussub.php index ffa88cb08..206fb309d 100644 --- a/plugins/OStatus/actions/ostatussub.php +++ b/plugins/OStatus/actions/ostatussub.php @@ -87,29 +87,35 @@ class OStatusSubAction extends Action */ function showPreviewForm() { + if ($this->oprofile->isGroup()) { + $this->previewGroup(); + } else { + $this->previewUser(); + } + + $this->elementStart('div', 'entity_actions'); + $this->elementStart('ul'); + $this->elementStart('li', 'entity_subscribe'); $this->elementStart('form', array('method' => 'post', 'id' => 'form_ostatus_sub', - 'class' => 'form_settings', + 'class' => 'form_remote_authorize', 'action' => common_local_url('ostatussub'))); - + $this->elementStart('fieldset'); $this->hidden('token', common_session_token()); $this->hidden('profile', $this->profile_uri); - - $this->elementStart('fieldset', array('id' => 'settings_feeds')); - if ($this->oprofile->isGroup()) { - $this->previewGroup(); - $this->submit('subscribe', _m('Join')); + $this->submit('submit', _m('Join'), 'submit', null, + _m('Join this group')); } else { - $this->previewUser(); - $this->submit('subscribe', _m('Subscribe')); + $this->submit('submit', _m('Subscribe'), 'submit', null, + _m('Subscribe to this user')); } - - $this->elementEnd('fieldset'); - $this->elementEnd('form'); + $this->elementEnd('li'); + $this->elementEnd('ul'); + $this->elementEnd('div'); } /** @@ -120,8 +126,7 @@ class OStatusSubAction extends Action $oprofile = $this->oprofile; $profile = $oprofile->localProfile(); - $this->text(sprintf(_m("Remote user %s"), $profile->nickname)); - // ... + $this->showEntity($profile); } /** @@ -132,8 +137,84 @@ class OStatusSubAction extends Action $oprofile = $this->oprofile; $group = $oprofile->localGroup(); - $this->text(sprintf(_m("Remote group %s"), $group->nickname)); - // .. + $this->showEntity($group); + } + + + function showEntity($entity) + { + $nickname = $entity->nickname; + $profile = $entity->profileurl; + $fullname = $entity->fullname; + $homepage = $entity->homepage; + $bio = $entity->bio; + $location = $entity->location; + $avatar = $entity->avatarurl; + + $this->elementStart('div', 'entity_profile vcard'); + $this->elementStart('dl', 'entity_depiction'); + $this->element('dt', null, _('Photo')); + $this->elementStart('dd'); + if ($avatar) { + $this->element('img', array('src' => $avatar, + 'class' => 'photo avatar', + 'width' => AVATAR_PROFILE_SIZE, + 'height' => AVATAR_PROFILE_SIZE, + 'alt' => $nickname)); + } + $this->elementEnd('dd'); + $this->elementEnd('dl'); + + $this->elementStart('dl', 'entity_nickname'); + $this->element('dt', null, _('Nickname')); + $this->elementStart('dd'); + $hasFN = ($fullname !== '') ? 'nickname' : 'fn nickname'; + $this->elementStart('a', array('href' => $profile, + 'class' => 'url '.$hasFN)); + $this->raw($nickname); + $this->elementEnd('a'); + $this->elementEnd('dd'); + $this->elementEnd('dl'); + + if (!is_null($fullname)) { + $this->elementStart('dl', 'entity_fn'); + $this->elementStart('dd'); + $this->elementStart('span', 'fn'); + $this->raw($fullname); + $this->elementEnd('span'); + $this->elementEnd('dd'); + $this->elementEnd('dl'); + } + if (!is_null($location)) { + $this->elementStart('dl', 'entity_location'); + $this->element('dt', null, _('Location')); + $this->elementStart('dd', 'label'); + $this->raw($location); + $this->elementEnd('dd'); + $this->elementEnd('dl'); + } + + if (!is_null($homepage)) { + $this->elementStart('dl', 'entity_url'); + $this->element('dt', null, _('URL')); + $this->elementStart('dd'); + $this->elementStart('a', array('href' => $homepage, + 'class' => 'url')); + $this->raw($homepage); + $this->elementEnd('a'); + $this->elementEnd('dd'); + $this->elementEnd('dl'); + } + + if (!is_null($bio)) { + $this->elementStart('dl', 'entity_note'); + $this->element('dt', null, _('Note')); + $this->elementStart('dd', 'note'); + $this->raw($bio); + $this->elementEnd('dd'); + $this->elementEnd('dl'); + } + $this->elementEnd('div'); } /** -- cgit v1.2.3-54-g00ecf From e070fcaaae3e6ac1fef1f9b066c5335fddb9376b Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Tue, 23 Feb 2010 11:37:49 -0800 Subject: OStatus: fix for avatars, submit button in updated remote profile preview --- plugins/OStatus/actions/ostatussub.php | 42 ++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 17 deletions(-) (limited to 'plugins/OStatus/actions/ostatussub.php') diff --git a/plugins/OStatus/actions/ostatussub.php b/plugins/OStatus/actions/ostatussub.php index 206fb309d..0d786fac9 100644 --- a/plugins/OStatus/actions/ostatussub.php +++ b/plugins/OStatus/actions/ostatussub.php @@ -126,7 +126,13 @@ class OStatusSubAction extends Action $oprofile = $this->oprofile; $profile = $oprofile->localProfile(); - $this->showEntity($profile); + $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE); + $avatarUrl = $avatar ? $avatar->displayUrl() : false; + + $this->showEntity($profile, + $profile->profileurl, + $avatarUrl, + $profile->bio); } /** @@ -137,31 +143,33 @@ class OStatusSubAction extends Action $oprofile = $this->oprofile; $group = $oprofile->localGroup(); - $this->showEntity($group); + $this->showEntity($group, + $group->getProfileUrl(), + $group->homepage_logo, + $group->description); } - function showEntity($entity) + function showEntity($entity, $profile, $avatar, $note) { $nickname = $entity->nickname; - $profile = $entity->profileurl; $fullname = $entity->fullname; $homepage = $entity->homepage; - $bio = $entity->bio; $location = $entity->location; - $avatar = $entity->avatarurl; + + if (!$avatar) { + $avatar = Avatar::defaultImage(AVATAR_PROFILE_SIZE); + } $this->elementStart('div', 'entity_profile vcard'); $this->elementStart('dl', 'entity_depiction'); $this->element('dt', null, _('Photo')); $this->elementStart('dd'); - if ($avatar) { - $this->element('img', array('src' => $avatar, - 'class' => 'photo avatar', - 'width' => AVATAR_PROFILE_SIZE, - 'height' => AVATAR_PROFILE_SIZE, - 'alt' => $nickname)); - } + $this->element('img', array('src' => $avatar, + 'class' => 'photo avatar', + 'width' => AVATAR_PROFILE_SIZE, + 'height' => AVATAR_PROFILE_SIZE, + 'alt' => $nickname)); $this->elementEnd('dd'); $this->elementEnd('dl'); @@ -206,11 +214,11 @@ class OStatusSubAction extends Action $this->elementEnd('dl'); } - if (!is_null($bio)) { + if (!is_null($note)) { $this->elementStart('dl', 'entity_note'); $this->element('dt', null, _('Note')); $this->elementStart('dd', 'note'); - $this->raw($bio); + $this->raw($note); $this->elementEnd('dd'); $this->elementEnd('dl'); } @@ -368,7 +376,7 @@ class OStatusSubAction extends Action } if ($this->validateFeed()) { - if ($this->arg('subscribe')) { + if ($this->arg('submit')) { $this->saveFeed(); return; } @@ -424,7 +432,7 @@ class OStatusSubAction extends Action function showPageNotice() { - if ($this->error) { + if (!empty($this->error)) { $this->element('p', 'error', $this->error); } } -- cgit v1.2.3-54-g00ecf From c79c70ea2c2dadafa72c65dc4593a66fecb070e3 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Tue, 23 Feb 2010 11:56:17 -0800 Subject: OStatus subscription UI tweak: if we're already subscribed/joined, say so and don't offer a 'subscribe'/'join' button on the profile preview page. --- plugins/OStatus/actions/ostatussub.php | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) (limited to 'plugins/OStatus/actions/ostatussub.php') diff --git a/plugins/OStatus/actions/ostatussub.php b/plugins/OStatus/actions/ostatussub.php index 0d786fac9..df9aa80b0 100644 --- a/plugins/OStatus/actions/ostatussub.php +++ b/plugins/OStatus/actions/ostatussub.php @@ -88,9 +88,13 @@ class OStatusSubAction extends Action function showPreviewForm() { if ($this->oprofile->isGroup()) { - $this->previewGroup(); + $ok = $this->previewGroup(); } else { - $this->previewUser(); + $ok = $this->previewUser(); + } + if (!$ok) { + // @fixme maybe provide a cancel button or link back? + return; } $this->elementStart('div', 'entity_actions'); @@ -120,12 +124,22 @@ class OStatusSubAction extends Action /** * Show a preview for a remote user's profile + * @return boolean true if we're ok to try subscribing */ function previewUser() { $oprofile = $this->oprofile; $profile = $oprofile->localProfile(); + $cur = common_current_user(); + if ($cur->isSubscribed($profile)) { + $this->element('div', array('class' => 'error'), + _m("You are already subscribed to this user.")); + $ok = false; + } else { + $ok = true; + } + $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE); $avatarUrl = $avatar ? $avatar->displayUrl() : false; @@ -133,20 +147,32 @@ class OStatusSubAction extends Action $profile->profileurl, $avatarUrl, $profile->bio); + return $ok; } /** * Show a preview for a remote group's profile + * @return boolean true if we're ok to try joining */ function previewGroup() { $oprofile = $this->oprofile; $group = $oprofile->localGroup(); + $cur = common_current_user(); + if ($cur->isMember($group)) { + $this->element('div', array('class' => 'error'), + _m("You are already a member of this group.")); + $ok = false; + } else { + $ok = true; + } + $this->showEntity($group, $group->getProfileUrl(), $group->homepage_logo, $group->description); + return $ok; } -- cgit v1.2.3-54-g00ecf From 90d34b26c66ceb5d37a9c2782356b46361a523cc Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Tue, 23 Feb 2010 20:44:27 +0000 Subject: OStatus: do PuSH subscription setup from subscribe/join event hooks, so resubscribing directly from a profile/group list works correctly if there aren't active subscriptions at the moment. --- lib/activity.php | 4 +- plugins/OStatus/OStatusPlugin.php | 158 +++++++++++++++++----------- plugins/OStatus/actions/ostatussub.php | 5 - plugins/OStatus/classes/Ostatus_profile.php | 26 ++++- 4 files changed, 127 insertions(+), 66 deletions(-) (limited to 'plugins/OStatus/actions/ostatussub.php') diff --git a/lib/activity.php b/lib/activity.php index 3689dac38..04c57c561 100644 --- a/lib/activity.php +++ b/lib/activity.php @@ -823,7 +823,9 @@ class Activity if ($namespace) { $attrs = array('xmlns' => 'http://www.w3.org/2005/Atom', 'xmlns:activity' => 'http://activitystrea.ms/spec/1.0/', - 'xmlns:ostatus' => 'http://ostatus.org/schema/1.0'); + 'xmlns:georss' => 'http://www.georss.org/georss', + 'xmlns:ostatus' => 'http://ostatus.org/schema/1.0', + 'xmlns:poco' => 'http://portablecontacts.net/spec/1.0'); } else { $attrs = array(); } diff --git a/plugins/OStatus/OStatusPlugin.php b/plugins/OStatus/OStatusPlugin.php index db4a0af35..629645767 100644 --- a/plugins/OStatus/OStatusPlugin.php +++ b/plugins/OStatus/OStatusPlugin.php @@ -251,58 +251,6 @@ class OStatusPlugin extends Plugin return true; } - /** - * Notify remote server and garbage collect unused feeds on unsubscribe. - * @fixme send these operations to background queues - * - * @param User $user - * @param Profile $other - * @return hook return value - */ - function onEndUnsubscribe($profile, $other) - { - $user = User::staticGet('id', $profile->id); - - if (empty($user)) { - return true; - } - - $oprofile = Ostatus_profile::staticGet('profile_id', $other->id); - - if (empty($oprofile)) { - return true; - } - - // Drop the PuSH subscription if there are no other subscribers. - - if ($other->subscriberCount() == 0) { - common_log(LOG_INFO, "Unsubscribing from now-unused feed $oprofile->feeduri"); - $oprofile->unsubscribe(); - } - - $act = new Activity(); - - $act->verb = ActivityVerb::UNFOLLOW; - - $act->id = TagURI::mint('unfollow:%d:%d:%s', - $profile->id, - $other->id, - common_date_iso8601(time())); - - $act->time = time(); - $act->title = _("Unfollow"); - $act->content = sprintf(_("%s stopped following %s."), - $profile->getBestName(), - $other->getBestName()); - - $act->actor = ActivityObject::fromProfile($profile); - $act->object = ActivityObject::fromProfile($other); - - $oprofile->notifyActivity($act); - - return true; - } - /** * Make sure necessary tables are filled out. */ @@ -366,6 +314,50 @@ class OStatusPlugin extends Plugin } } + /** + * When about to subscribe to a remote user, start a server-to-server + * PuSH subscription if needed. If we can't establish that, abort. + * + * @fixme If something else aborts later, we could end up with a stray + * PuSH subscription. This is relatively harmless, though. + * + * @param Profile $subscriber + * @param Profile $other + * + * @return hook return code + * + * @throws Exception + */ + function onStartSubscribe($subscriber, $other) + { + $user = User::staticGet('id', $subscriber->id); + + if (empty($user)) { + return true; + } + + $oprofile = Ostatus_profile::staticGet('profile_id', $other->id); + + if (empty($oprofile)) { + return true; + } + + if (!$oprofile->subscribe()) { + throw new Exception(_m('Could not set up remote subscription.')); + } + } + + /** + * Having established a remote subscription, send a notification to the + * remote OStatus profile's endpoint. + * + * @param Profile $subscriber + * @param Profile $other + * + * @return hook return code + * + * @throws Exception + */ function onEndSubscribe($subscriber, $other) { $user = User::staticGet('id', $subscriber->id); @@ -403,6 +395,54 @@ class OStatusPlugin extends Plugin return true; } + /** + * Notify remote server and garbage collect unused feeds on unsubscribe. + * @fixme send these operations to background queues + * + * @param User $user + * @param Profile $other + * @return hook return value + */ + function onEndUnsubscribe($profile, $other) + { + $user = User::staticGet('id', $profile->id); + + if (empty($user)) { + return true; + } + + $oprofile = Ostatus_profile::staticGet('profile_id', $other->id); + + if (empty($oprofile)) { + return true; + } + + // Drop the PuSH subscription if there are no other subscribers. + $oprofile->garbageCollect(); + + $act = new Activity(); + + $act->verb = ActivityVerb::UNFOLLOW; + + $act->id = TagURI::mint('unfollow:%d:%d:%s', + $profile->id, + $other->id, + common_date_iso8601(time())); + + $act->time = time(); + $act->title = _("Unfollow"); + $act->content = sprintf(_("%s stopped following %s."), + $profile->getBestName(), + $other->getBestName()); + + $act->actor = ActivityObject::fromProfile($profile); + $act->object = ActivityObject::fromProfile($other); + + $oprofile->notifyActivity($act); + + return true; + } + /** * When one of our local users tries to join a remote group, * notify the remote server. If the notification is rejected, @@ -418,6 +458,10 @@ class OStatusPlugin extends Plugin { $oprofile = Ostatus_profile::staticGet('group_id', $group->id); if ($oprofile) { + if (!$oprofile->subscribe()) { + throw new Exception(_m('Could not set up remote group membership.')); + } + $member = Profile::staticGet($user->id); $act = new Activity(); @@ -439,7 +483,8 @@ class OStatusPlugin extends Plugin if ($oprofile->notifyActivity($act)) { return true; } else { - throw new ServerException(_m("Failed joining remote group.")); + $oprofile->garbageCollect(); + throw new Exception(_m("Failed joining remote group.")); } } } @@ -464,12 +509,7 @@ class OStatusPlugin extends Plugin $oprofile = Ostatus_profile::staticGet('group_id', $group->id); if ($oprofile) { // Drop the PuSH subscription if there are no other subscribers. - - $members = $group->getMembers(0, 1); - if ($members->N == 0) { - common_log(LOG_INFO, "Unsubscribing from now-unused group feed $oprofile->feeduri"); - $oprofile->unsubscribe(); - } + $oprofile->garbageCollect(); $member = Profile::staticGet($user->id); diff --git a/plugins/OStatus/actions/ostatussub.php b/plugins/OStatus/actions/ostatussub.php index df9aa80b0..b3569e695 100644 --- a/plugins/OStatus/actions/ostatussub.php +++ b/plugins/OStatus/actions/ostatussub.php @@ -324,11 +324,6 @@ class OStatusSubAction extends Action // And subscribe the current user to the local profile $user = common_current_user(); - if (!$this->oprofile->subscribe()) { - $this->showForm(_m("Failed to set up server-to-server subscription.")); - return; - } - if ($this->oprofile->isGroup()) { $group = $this->oprofile->localGroup(); if ($user->isMember($group)) { diff --git a/plugins/OStatus/classes/Ostatus_profile.php b/plugins/OStatus/classes/Ostatus_profile.php index e8cc13c6c..91b957fa2 100644 --- a/plugins/OStatus/classes/Ostatus_profile.php +++ b/plugins/OStatus/classes/Ostatus_profile.php @@ -346,6 +346,29 @@ class Ostatus_profile extends Memcached_DataObject } } + /** + * Check if this remote profile has any active local subscriptions, and + * if not drop the PuSH subscription feed. + * + * @return boolean + */ + public function garbageCollect() + { + if ($this->isGroup()) { + $members = $this->localGroup()->getMembers(0, 1); + $count = $members->N; + } else { + $count = $this->localProfile()->subscriberCount(); + } + if ($count == 0) { + common_log(LOG_INFO, "Unsubscribing from now-unused remote feed $oprofile->feeduri"); + $this->unsubscribe(); + return true; + } else { + return false; + } + } + /** * Send an Activity Streams notification to the remote Salmon endpoint, * if so configured. @@ -379,7 +402,8 @@ class Ostatus_profile extends Memcached_DataObject 'xmlns:activity' => 'http://activitystrea.ms/spec/1.0/', 'xmlns:thr' => 'http://purl.org/syndication/thread/1.0', 'xmlns:georss' => 'http://www.georss.org/georss', - 'xmlns:ostatus' => 'http://ostatus.org/schema/1.0'); + 'xmlns:ostatus' => 'http://ostatus.org/schema/1.0', + 'xmlns:poco' => 'http://portablecontacts.net/spec/1.0'); $entry = new XMLStringer(); $entry->elementStart('entry', $attributes); -- cgit v1.2.3-54-g00ecf From 5f9a8ca64bee5247358238c26b4f54003337d11b Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Tue, 23 Feb 2010 21:11:44 +0000 Subject: OStatus: accept webfinger addresses as well as profile URLs in the explicit remote subscribe form. --- plugins/OStatus/actions/ostatussub.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'plugins/OStatus/actions/ostatussub.php') diff --git a/plugins/OStatus/actions/ostatussub.php b/plugins/OStatus/actions/ostatussub.php index b3569e695..12832cdcf 100644 --- a/plugins/OStatus/actions/ostatussub.php +++ b/plugins/OStatus/actions/ostatussub.php @@ -288,10 +288,15 @@ class OStatusSubAction extends Action } $this->profile_uri = $profile_uri; - // @fixme validate, normalize bla bla try { - $oprofile = Ostatus_profile::ensureProfile($this->profile_uri); - $this->oprofile = $oprofile; + if (Validate::email($this->profile_uri)) { + $this->oprofile = Ostatus_profile::ensureWebfinger($this->profile_uri); + } else if (Validate::uri($this->profile_uri)) { + $this->oprofile = Ostatus_profile::ensureProfile($this->profile_uri); + } else { + $this->error = _m("Invalid address format."); + return false; + } return true; } catch (FeedSubBadURLException $e) { $this->error = _m('Invalid URL or could not reach server.'); -- cgit v1.2.3-54-g00ecf From b5b5184c885e74d9532409a5962f851c4baf41c4 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Thu, 25 Feb 2010 13:02:08 -0800 Subject: OStatus: fix remote groups to work with new user_groups/local_groups split. - fix generation so we get the profile info (what's available so far) - use id instead of nickname for group join/leave forms so we can join/leave remote groups while the rest of the groups UI remains limited to local groups (plugins are responsible for making sure remote notifications and permission checks are done) - fix remote notification when joining group through OStatus's remote subscribe form --- actions/joingroup.php | 39 ++++++++++++++++------------- actions/leavegroup.php | 39 ++++++++++++++++------------- classes/User_group.php | 2 +- lib/activity.php | 7 ++++-- lib/joinform.php | 2 +- lib/leaveform.php | 2 +- lib/router.php | 3 +++ plugins/OStatus/actions/ostatussub.php | 14 ++++++++--- plugins/OStatus/classes/Ostatus_profile.php | 26 +++++++++++-------- 9 files changed, 79 insertions(+), 55 deletions(-) (limited to 'plugins/OStatus/actions/ostatussub.php') diff --git a/actions/joingroup.php b/actions/joingroup.php index ba642f712..f87e5dae2 100644 --- a/actions/joingroup.php +++ b/actions/joingroup.php @@ -62,30 +62,33 @@ class JoingroupAction extends Action } $nickname_arg = $this->trimmed('nickname'); - $nickname = common_canonical_nickname($nickname_arg); - - // Permanent redirect on non-canonical nickname + $id = intval($this->arg('id')); + if ($id) { + $this->group = User_group::staticGet('id', $id); + } else if ($nickname_arg) { + $nickname = common_canonical_nickname($nickname_arg); + + // Permanent redirect on non-canonical nickname + + if ($nickname_arg != $nickname) { + $args = array('nickname' => $nickname); + common_redirect(common_local_url('leavegroup', $args), 301); + return false; + } - if ($nickname_arg != $nickname) { - $args = array('nickname' => $nickname); - common_redirect(common_local_url('joingroup', $args), 301); - return false; - } + $local = Local_group::staticGet('nickname', $nickname); - if (!$nickname) { - $this->clientError(_('No nickname.'), 404); - return false; - } - - $local = Local_group::staticGet('nickname', $nickname); + if (!$local) { + $this->clientError(_('No such group.'), 404); + return false; + } - if (!$local) { - $this->clientError(_('No such group.'), 404); + $this->group = User_group::staticGet('id', $local->group_id); + } else { + $this->clientError(_('No nickname or ID.'), 404); return false; } - $this->group = User_group::staticGet('id', $local->group_id); - if (!$this->group) { $this->clientError(_('No such group.'), 404); return false; diff --git a/actions/leavegroup.php b/actions/leavegroup.php index 222d4c1b4..329b5aafe 100644 --- a/actions/leavegroup.php +++ b/actions/leavegroup.php @@ -62,30 +62,33 @@ class LeavegroupAction extends Action } $nickname_arg = $this->trimmed('nickname'); - $nickname = common_canonical_nickname($nickname_arg); - - // Permanent redirect on non-canonical nickname + $id = intval($this->arg('id')); + if ($id) { + $this->group = User_group::staticGet('id', $id); + } else if ($nickname_arg) { + $nickname = common_canonical_nickname($nickname_arg); + + // Permanent redirect on non-canonical nickname + + if ($nickname_arg != $nickname) { + $args = array('nickname' => $nickname); + common_redirect(common_local_url('leavegroup', $args), 301); + return false; + } - if ($nickname_arg != $nickname) { - $args = array('nickname' => $nickname); - common_redirect(common_local_url('leavegroup', $args), 301); - return false; - } + $local = Local_group::staticGet('nickname', $nickname); - if (!$nickname) { - $this->clientError(_('No nickname.'), 404); - return false; - } - - $local = Local_group::staticGet('nickname', $nickname); + if (!$local) { + $this->clientError(_('No such group.'), 404); + return false; + } - if (!$local) { - $this->clientError(_('No such group.'), 404); + $this->group = User_group::staticGet('id', $local->group_id); + } else { + $this->clientError(_('No nickname or ID.'), 404); return false; } - $this->group = User_group::staticGet('id', $local->group_id); - if (!$this->group) { $this->clientError(_('No such group.'), 404); return false; diff --git a/classes/User_group.php b/classes/User_group.php index f24bef764..2a58d8895 100644 --- a/classes/User_group.php +++ b/classes/User_group.php @@ -404,7 +404,7 @@ class User_group extends Memcached_DataObject $xs = new XMLStringer(true); $xs->elementStart('activity:subject'); - $xs->element('activity:object', null, 'http://activitystrea.ms/schema/1.0/group'); + $xs->element('activity:object-type', null, 'http://activitystrea.ms/schema/1.0/group'); $xs->element('id', null, $this->permalink()); $xs->element('title', null, $this->getBestName()); $xs->element( diff --git a/lib/activity.php b/lib/activity.php index e592aad6f..4e7ff5336 100644 --- a/lib/activity.php +++ b/lib/activity.php @@ -610,7 +610,10 @@ class ActivityObject $object->id = $profile->getUri(); $object->title = $profile->getBestName(); $object->link = $profile->profileurl; - $object->avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE); + $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE); + if ($avatar) { + $object->avatar = $avatar->displayUrl(); + } if (isset($profile->lat) && isset($profile->lon)) { $object->geopoint = (float)$profile->lat . ' ' . (float)$profile->lon; @@ -664,7 +667,7 @@ class ActivityObject 'rel' => 'avatar', 'href' => empty($this->avatar) ? Avatar::defaultImage(AVATAR_PROFILE_SIZE) - : $this->avatar->displayUrl() + : $this->avatar ), null ); diff --git a/lib/joinform.php b/lib/joinform.php index aefb553aa..aa8bc20e2 100644 --- a/lib/joinform.php +++ b/lib/joinform.php @@ -100,7 +100,7 @@ class JoinForm extends Form function action() { return common_local_url('joingroup', - array('nickname' => $this->group->nickname)); + array('id' => $this->group->id)); } /** diff --git a/lib/leaveform.php b/lib/leaveform.php index e63d96ee8..5469b5704 100644 --- a/lib/leaveform.php +++ b/lib/leaveform.php @@ -100,7 +100,7 @@ class LeaveForm extends Form function action() { return common_local_url('leavegroup', - array('nickname' => $this->group->nickname)); + array('id' => $this->group->id)); } /** diff --git a/lib/router.php b/lib/router.php index 987d0152e..0e15d83b9 100644 --- a/lib/router.php +++ b/lib/router.php @@ -247,6 +247,9 @@ class Router $m->connect('group/:nickname/'.$v, array('action' => $v.'group'), array('nickname' => '[a-zA-Z0-9]+')); + $m->connect('group/:id/id/'.$v, + array('action' => $v.'group'), + array('id' => '[0-9]+')); } foreach (array('members', 'logo', 'rss', 'designsettings') as $n) { diff --git a/plugins/OStatus/actions/ostatussub.php b/plugins/OStatus/actions/ostatussub.php index 12832cdcf..aae22f868 100644 --- a/plugins/OStatus/actions/ostatussub.php +++ b/plugins/OStatus/actions/ostatussub.php @@ -333,10 +333,18 @@ class OStatusSubAction extends Action $group = $this->oprofile->localGroup(); if ($user->isMember($group)) { $this->showForm(_m('Already a member!')); - } elseif (Group_member::join($this->oprofile->group_id, $user->id)) { - $this->successGroup(); + return; + } + if (Event::handle('StartJoinGroup', array($group, $user))) { + $ok = Group_member::join($this->oprofile->group_id, $user->id); + if ($ok) { + Event::handle('EndJoinGroup', array($group, $user)); + $this->successGroup(); + } else { + $this->showForm(_m('Remote group join failed!')); + } } else { - $this->showForm(_m('Remote group join failed!')); + $this->showForm(_m('Remote group join aborted!')); } } else { $local = $this->oprofile->localProfile(); diff --git a/plugins/OStatus/classes/Ostatus_profile.php b/plugins/OStatus/classes/Ostatus_profile.php index d66939399..f23017077 100644 --- a/plugins/OStatus/classes/Ostatus_profile.php +++ b/plugins/OStatus/classes/Ostatus_profile.php @@ -162,7 +162,7 @@ class Ostatus_profile extends Memcached_DataObject 'jpg' => 'image/jpeg', 'jpeg' => 'image/jpeg', 'gif' => 'image/gif'); - $extension = pathinfo(parse_url($avatarHref, PHP_URL_PATH), PATHINFO_EXTENSION); + $extension = pathinfo(parse_url($object->avatar, PHP_URL_PATH), PATHINFO_EXTENSION); if (isset($map[$extension])) { // @fixme this ain't used/saved yet $object->avatarType = $map[$extension]; @@ -332,6 +332,9 @@ class Ostatus_profile extends Memcached_DataObject */ public function unsubscribe() { $feedsub = FeedSub::staticGet('uri', $this->feeduri); + if (!$feedsub) { + return true; + } if ($feedsub->sub_state == 'active') { return $feedsub->unsubscribe(); } else if ($feedsub->sub_state == '' || $feedsub->sub_state == 'inactive' || $feedsub->sub_state == 'unsubscribe') { @@ -356,7 +359,7 @@ class Ostatus_profile extends Memcached_DataObject $count = $this->localProfile()->subscriberCount(); } if ($count == 0) { - common_log(LOG_INFO, "Unsubscribing from now-unused remote feed $oprofile->feeduri"); + common_log(LOG_INFO, "Unsubscribing from now-unused remote feed $this->feeduri"); $this->unsubscribe(); return true; } else { @@ -1095,8 +1098,8 @@ class Ostatus_profile extends Memcached_DataObject if ($object->type == ActivityObject::PERSON) { $profile = new Profile(); + $profile->created = common_sql_now(); self::updateProfile($profile, $object, $hints); - $profile->created = common_sql_now(); $oprofile->profile_id = $profile->insert(); if (!$oprofile->profile_id) { @@ -1104,6 +1107,7 @@ class Ostatus_profile extends Memcached_DataObject } } else { $group = new User_group(); + $group->uri = $homeuri; $group->created = common_sql_now(); self::updateGroup($group, $object, $hints); @@ -1183,19 +1187,19 @@ class Ostatus_profile extends Memcached_DataObject { $orig = clone($group); - // @fixme need to make nick unique etc *hack hack* $group->nickname = self::getActivityObjectNickname($object, $hints); $group->fullname = $object->title; - // @fixme no canonical profileurl; using homepage instead for now - $group->homepage = $object->id; + if (!empty($object->link)) { + $group->mainpage = $object->link; + } else if (array_key_exists('profileurl', $hints)) { + $group->mainpage = $hints['profileurl']; + } - // @fixme homepage - // @fixme bio - // @fixme tags/categories - // @fixme location? // @todo tags from categories - // @todo lat/lon/location? + $group->description = self::getActivityObjectBio($object, $hints); + $group->location = self::getActivityObjectLocation($object, $hints); + $group->homepage = self::getActivityObjectHomepage($object, $hints); if ($group->id) { common_log(LOG_DEBUG, "Updating OStatus group $group->id from remote info $object->id: " . var_export($object, true) . var_export($hints, true)); -- cgit v1.2.3-54-g00ecf From 00f724d0e6380f8177bcee0ff2631783f514508a Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Mon, 1 Mar 2010 14:10:13 -0800 Subject: Localization tweak: include doc comments marked as 'TRANS' in .po file output; these should now get automatically pulled through to the TranslateWiki interface as translator help hints. --- plugins/OStatus/actions/ostatussub.php | 6 + plugins/OStatus/locale/OStatus.po | 280 ++++++++++++++++++++++++++++----- scripts/update_po_templates.php | 7 +- 3 files changed, 256 insertions(+), 37 deletions(-) (limited to 'plugins/OStatus/actions/ostatussub.php') diff --git a/plugins/OStatus/actions/ostatussub.php b/plugins/OStatus/actions/ostatussub.php index aae22f868..f45e6a8d1 100644 --- a/plugins/OStatus/actions/ostatussub.php +++ b/plugins/OStatus/actions/ostatussub.php @@ -332,6 +332,7 @@ class OStatusSubAction extends Action if ($this->oprofile->isGroup()) { $group = $this->oprofile->localGroup(); if ($user->isMember($group)) { + // TRANS: OStatus remote group subscription dialog error. $this->showForm(_m('Already a member!')); return; } @@ -341,18 +342,22 @@ class OStatusSubAction extends Action Event::handle('EndJoinGroup', array($group, $user)); $this->successGroup(); } else { + // TRANS: OStatus remote group subscription dialog error. $this->showForm(_m('Remote group join failed!')); } } else { + // TRANS: OStatus remote group subscription dialog error. $this->showForm(_m('Remote group join aborted!')); } } else { $local = $this->oprofile->localProfile(); if ($user->isSubscribed($local)) { + // TRANS: OStatus remote subscription dialog error. $this->showForm(_m('Already subscribed!')); } elseif ($this->oprofile->subscribeLocalToRemote($user)) { $this->successUser(); } else { + // TRANS: OStatus remote subscription dialog error. $this->showForm(_m('Remote subscription failed!')); } } @@ -450,6 +455,7 @@ class OStatusSubAction extends Action function title() { + // TRANS: Page title for OStatus remote subscription form return _m('Authorize subscription'); } diff --git a/plugins/OStatus/locale/OStatus.po b/plugins/OStatus/locale/OStatus.po index dedc018e3..ee19cf3db 100644 --- a/plugins/OStatus/locale/OStatus.po +++ b/plugins/OStatus/locale/OStatus.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-12-07 20:38-0800\n" +"POT-Creation-Date: 2010-03-01 14:08-0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -16,89 +16,297 @@ msgstr "" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: tests/gettext-speedtest.php:57 FeedSubPlugin.php:76 -msgid "Feeds" +#: actions/groupsalmon.php:51 +msgid "Can't accept remote posts for a remote group." +msgstr "" + +#: actions/groupsalmon.php:123 +msgid "Can't read profile to set up group membership." msgstr "" -#: FeedSubPlugin.php:77 -msgid "Feed subscription options" +#: actions/groupsalmon.php:126 actions/groupsalmon.php:169 +msgid "Groups can't join groups." msgstr "" -#: feedmunger.php:215 +#: actions/groupsalmon.php:153 #, php-format -msgid "New post: \"%1$s\" %2$s" +msgid "Could not join remote user %1$s to group %2$s." msgstr "" -#: actions/feedsubsettings.php:41 -msgid "Feed subscriptions" +#: actions/groupsalmon.php:166 +msgid "Can't read profile to cancel group membership." msgstr "" -#: actions/feedsubsettings.php:52 -msgid "" -"You can subscribe to feeds from other sites; updates will appear in your " -"personal timeline." +#: actions/groupsalmon.php:182 +#, php-format +msgid "Could not remove remote user %1$s from group %2$s." +msgstr "" + +#: actions/ostatusinit.php:40 +msgid "You can use the local subscription!" +msgstr "" + +#: actions/ostatusinit.php:61 +msgid "There was a problem with your session token. Try again, please." +msgstr "" + +#: actions/ostatusinit.php:79 actions/ostatussub.php:439 +msgid "Subscribe to user" +msgstr "" + +#: actions/ostatusinit.php:97 +#, php-format +msgid "Subscribe to %s" msgstr "" -#: actions/feedsubsettings.php:96 +#: actions/ostatusinit.php:102 +msgid "User nickname" +msgstr "" + +#: actions/ostatusinit.php:103 +msgid "Nickname of the user you want to follow" +msgstr "" + +#: actions/ostatusinit.php:106 +msgid "Profile Account" +msgstr "" + +#: actions/ostatusinit.php:107 +msgid "Your account id (i.e. user@identi.ca)" +msgstr "" + +#: actions/ostatusinit.php:110 actions/ostatussub.php:115 +#: OStatusPlugin.php:205 msgid "Subscribe" msgstr "" -#: actions/feedsubsettings.php:98 +#: actions/ostatusinit.php:128 +msgid "Must provide a remote profile." +msgstr "" + +#: actions/ostatusinit.php:138 +msgid "Couldn't look up OStatus account profile." +msgstr "" + +#: actions/ostatusinit.php:153 +msgid "Couldn't confirm remote profile address." +msgstr "" + +#: actions/ostatusinit.php:171 +msgid "OStatus Connect" +msgstr "" + +#: actions/ostatussub.php:68 +msgid "Address or profile URL" +msgstr "" + +#: actions/ostatussub.php:70 +msgid "Enter the profile URL of a PubSubHubbub-enabled feed" +msgstr "" + +#: actions/ostatussub.php:74 msgid "Continue" msgstr "" -#: actions/feedsubsettings.php:151 -msgid "Empty feed URL!" +#: actions/ostatussub.php:112 OStatusPlugin.php:503 +msgid "Join" +msgstr "" + +#: actions/ostatussub.php:113 +msgid "Join this group" +msgstr "" + +#: actions/ostatussub.php:116 +msgid "Subscribe to this user" +msgstr "" + +#: actions/ostatussub.php:137 +msgid "You are already subscribed to this user." +msgstr "" + +#: actions/ostatussub.php:165 +msgid "You are already a member of this group." msgstr "" -#: actions/feedsubsettings.php:161 +#: actions/ostatussub.php:286 +msgid "Empty remote profile URL!" +msgstr "" + +#: actions/ostatussub.php:297 +msgid "Invalid address format." +msgstr "" + +#: actions/ostatussub.php:302 msgid "Invalid URL or could not reach server." msgstr "" -#: actions/feedsubsettings.php:164 +#: actions/ostatussub.php:304 msgid "Cannot read feed; server returned error." msgstr "" -#: actions/feedsubsettings.php:167 +#: actions/ostatussub.php:306 msgid "Cannot read feed; server returned an empty page." msgstr "" -#: actions/feedsubsettings.php:170 +#: actions/ostatussub.php:308 msgid "Bad HTML, could not find feed link." msgstr "" -#: actions/feedsubsettings.php:173 +#: actions/ostatussub.php:310 msgid "Could not find a feed linked from this URL." msgstr "" -#: actions/feedsubsettings.php:176 +#: actions/ostatussub.php:312 msgid "Not a recognized feed type." msgstr "" -#: actions/feedsubsettings.php:180 -msgid "Bad feed URL." +#: actions/ostatussub.php:315 +#, php-format +msgid "Bad feed URL: %s %s" +msgstr "" + +#. TRANS: OStatus remote group subscription dialog error. +#: actions/ostatussub.php:336 +msgid "Already a member!" msgstr "" -#: actions/feedsubsettings.php:188 -msgid "Feed is not PuSH-enabled; cannot subscribe." +#. TRANS: OStatus remote group subscription dialog error. +#: actions/ostatussub.php:346 +msgid "Remote group join failed!" msgstr "" -#: actions/feedsubsettings.php:208 -msgid "Feed subscription failed! Bad response from hub." +#. TRANS: OStatus remote group subscription dialog error. +#: actions/ostatussub.php:350 +msgid "Remote group join aborted!" msgstr "" -#: actions/feedsubsettings.php:218 +#. TRANS: OStatus remote subscription dialog error. +#: actions/ostatussub.php:356 msgid "Already subscribed!" msgstr "" -#: actions/feedsubsettings.php:220 -msgid "Feed subscribed!" +#. TRANS: OStatus remote subscription dialog error. +#: actions/ostatussub.php:361 +msgid "Remote subscription failed!" msgstr "" -#: actions/feedsubsettings.php:222 -msgid "Feed subscription failed!" +#. TRANS: Page title for OStatus remote subscription form +#: actions/ostatussub.php:459 +msgid "Authorize subscription" +msgstr "" + +#: actions/ostatussub.php:470 +msgid "" +"You can subscribe to users from other supported sites. Paste their address " +"or profile URI below:" +msgstr "" + +#: classes/Ostatus_profile.php:789 +#, php-format +msgid "Tried to update avatar for unsaved remote profile %s" msgstr "" -#: actions/feedsubsettings.php:231 -msgid "Previewing feed:" +#: classes/Ostatus_profile.php:797 +#, php-format +msgid "Unable to fetch avatar from %s" +msgstr "" + +#: lib/salmonaction.php:41 +msgid "This method requires a POST." +msgstr "" + +#: lib/salmonaction.php:45 +msgid "Salmon requires application/magic-envelope+xml" +msgstr "" + +#: lib/salmonaction.php:55 +msgid "Salmon signature verification failed." +msgstr "" + +#: lib/salmonaction.php:66 +msgid "Salmon post must be an Atom entry." +msgstr "" + +#: lib/salmonaction.php:114 +msgid "Unrecognized activity type." +msgstr "" + +#: lib/salmonaction.php:122 +msgid "This target doesn't understand posts." +msgstr "" + +#: lib/salmonaction.php:127 +msgid "This target doesn't understand follows." +msgstr "" + +#: lib/salmonaction.php:132 +msgid "This target doesn't understand unfollows." +msgstr "" + +#: lib/salmonaction.php:137 +msgid "This target doesn't understand favorites." +msgstr "" + +#: lib/salmonaction.php:142 +msgid "This target doesn't understand unfavorites." +msgstr "" + +#: lib/salmonaction.php:147 +msgid "This target doesn't understand share events." +msgstr "" + +#: lib/salmonaction.php:152 +msgid "This target doesn't understand joins." +msgstr "" + +#: lib/salmonaction.php:157 +msgid "This target doesn't understand leave events." +msgstr "" + +#: OStatusPlugin.php:319 +#, php-format +msgid "Sent from %s via OStatus" +msgstr "" + +#: OStatusPlugin.php:371 +msgid "Could not set up remote subscription." +msgstr "" + +#: OStatusPlugin.php:487 +msgid "Could not set up remote group membership." +msgstr "" + +#: OStatusPlugin.php:504 +#, php-format +msgid "%s has joined group %s." +msgstr "" + +#: OStatusPlugin.php:512 +msgid "Failed joining remote group." +msgstr "" + +#: OStatusPlugin.php:553 +msgid "Leave" +msgstr "" + +#: OStatusPlugin.php:554 +#, php-format +msgid "%s has left group %s." +msgstr "" + +#: OStatusPlugin.php:685 +msgid "Subscribe to remote user" +msgstr "" + +#: OStatusPlugin.php:726 +msgid "Profile update" +msgstr "" + +#: OStatusPlugin.php:727 +#, php-format +msgid "%s has updated their profile page." +msgstr "" + +#: tests/gettext-speedtest.php:57 +msgid "Feeds" msgstr "" diff --git a/scripts/update_po_templates.php b/scripts/update_po_templates.php index 61a6ac783..0bfa62a22 100755 --- a/scripts/update_po_templates.php +++ b/scripts/update_po_templates.php @@ -36,7 +36,11 @@ xgettext \ --default-domain=$domain \ --output=locale/$domain.po \ --language=PHP \ - --keyword="_m:1" \ + --add-comments=TRANS \ + --keyword="_m:1,1t" \ + --keyword="_m:1c,2,2t" \ + --keyword="_m:1,2,3t" \ + --keyword="_m:1c,2,3,4t" \ --keyword="pgettext:1c,2" \ --keyword="npgettext:1c,2,3" \ actions/*.php \ @@ -62,6 +66,7 @@ xgettext \ --default-domain=$domain \ --output=locale/$domain.po \ --language=PHP \ + --add-comments=TRANS \ --keyword='' \ --keyword="_m:1,1t" \ --keyword="_m:1c,2,2t" \ -- cgit v1.2.3-54-g00ecf From 623faf9f2d83b8fd6134e77ad6f5dd1cedc7a5c1 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Tue, 2 Mar 2010 09:57:28 -0500 Subject: Just a label change. Since the user already went ahead with subscribing, in this step we are just confirming the profile. --- plugins/OStatus/actions/ostatussub.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins/OStatus/actions/ostatussub.php') diff --git a/plugins/OStatus/actions/ostatussub.php b/plugins/OStatus/actions/ostatussub.php index f45e6a8d1..e318701a2 100644 --- a/plugins/OStatus/actions/ostatussub.php +++ b/plugins/OStatus/actions/ostatussub.php @@ -112,7 +112,7 @@ class OStatusSubAction extends Action $this->submit('submit', _m('Join'), 'submit', null, _m('Join this group')); } else { - $this->submit('submit', _m('Subscribe'), 'submit', null, + $this->submit('submit', _m('Confirm'), 'submit', null, _m('Subscribe to this user')); } $this->elementEnd('fieldset'); -- cgit v1.2.3-54-g00ecf From a42d1116db06539f2da4eb5332bbdbef5beda3fe Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Wed, 3 Mar 2010 13:40:26 -0800 Subject: Separate the UI paths for ostatussub and ostatusgroup. They'll redirect to each other transparently if they find you've put a remote entity of the other type. --- plugins/OStatus/OStatusPlugin.php | 12 +- plugins/OStatus/actions/ostatusgroup.php | 181 +++++++++++++++++++++++++++++++ plugins/OStatus/actions/ostatussub.php | 134 +++++++---------------- 3 files changed, 224 insertions(+), 103 deletions(-) create mode 100644 plugins/OStatus/actions/ostatusgroup.php (limited to 'plugins/OStatus/actions/ostatussub.php') diff --git a/plugins/OStatus/OStatusPlugin.php b/plugins/OStatus/OStatusPlugin.php index dc502e52c..b4b446a7f 100644 --- a/plugins/OStatus/OStatusPlugin.php +++ b/plugins/OStatus/OStatusPlugin.php @@ -51,8 +51,8 @@ class OStatusPlugin extends Plugin array('action' => 'ostatusinit'), array('nickname' => '[A-Za-z0-9_-]+')); $m->connect('main/ostatussub', array('action' => 'ostatussub')); - $m->connect('main/ostatussub', - array('action' => 'ostatussub'), array('feed' => '[A-Za-z0-9\.\/\:]+')); + $m->connect('main/ostatusgroup', + array('action' => 'ostatusgroup')); // PuSH actions $m->connect('main/push/hub', array('action' => 'pushhub')); @@ -731,7 +731,7 @@ class OStatusPlugin extends Plugin function onStartShowUserGroupsContent($action) { - $this->showEntityRemoteSubscribe($action); + $this->showEntityRemoteSubscribe($action, 'ostatusgroup'); return true; } @@ -745,19 +745,19 @@ class OStatusPlugin extends Plugin function onEndShowGroupsMiniList($action) { - $this->showEntityRemoteSubscribe($action); + $this->showEntityRemoteSubscribe($action, 'ostatusgroup'); return true; } - function showEntityRemoteSubscribe($action) + function showEntityRemoteSubscribe($action, $target='ostatussub') { $user = common_current_user(); if ($user && ($user->id == $action->profile->id)) { $action->elementStart('div', 'entity_actions'); $action->elementStart('p', array('id' => 'entity_remote_subscribe', 'class' => 'entity_subscribe')); - $action->element('a', array('href' => common_local_url('ostatussub'), + $action->element('a', array('href' => common_local_url($target), 'class' => 'entity_remote_subscribe') , _m('Remote')); $action->elementEnd('p'); diff --git a/plugins/OStatus/actions/ostatusgroup.php b/plugins/OStatus/actions/ostatusgroup.php new file mode 100644 index 000000000..4fcd0eb39 --- /dev/null +++ b/plugins/OStatus/actions/ostatusgroup.php @@ -0,0 +1,181 @@ +. + */ + +/** + * @package OStatusPlugin + * @maintainer Brion Vibber + */ + +if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } + +/** + * Key UI methods: + * + * showInputForm() - form asking for a remote profile account or URL + * We end up back here on errors + * + * showPreviewForm() - surrounding form for preview-and-confirm + * preview() - display profile for a remote group + * + * success() - redirects to groups page on join + */ +class OStatusGroupAction extends OStatusSubAction +{ + protected $profile_uri; // provided acct: or URI of remote entity + protected $oprofile; // Ostatus_profile of remote entity, if valid + + + function validateRemoteProfile() + { + if (!$this->oprofile->isGroup()) { + // Send us to the user subscription form for conf + $target = common_local_url('ostatussub', array(), array('profile' => $this->profile_uri)); + common_redirect($target, 303); + } + } + + /** + * Show the initial form, when we haven't yet been given a valid + * remote profile. + */ + function showInputForm() + { + $user = common_current_user(); + + $profile = $user->getProfile(); + + $this->elementStart('form', array('method' => 'post', + 'id' => 'form_ostatus_sub', + 'class' => 'form_settings', + 'action' => $this->selfLink())); + + $this->hidden('token', common_session_token()); + + $this->elementStart('fieldset', array('id' => 'settings_feeds')); + + $this->elementStart('ul', 'form_data'); + $this->elementStart('li'); + $this->input('profile', + _m('Group profile URL'), + $this->profile_uri, + _m('Enter the profile URL of a group on another StatusNet site')); + $this->elementEnd('li'); + $this->elementEnd('ul'); + + $this->submit('validate', _m('Continue')); + + $this->elementEnd('fieldset'); + + $this->elementEnd('form'); + } + + /** + * Show a preview for a remote group's profile + * @return boolean true if we're ok to try joining + */ + function preview() + { + $oprofile = $this->oprofile; + $group = $oprofile->localGroup(); + + $cur = common_current_user(); + if ($cur->isMember($group)) { + $this->element('div', array('class' => 'error'), + _m("You are already a member of this group.")); + $ok = false; + } else { + $ok = true; + } + + $this->showEntity($group, + $group->getProfileUrl(), + $group->homepage_logo, + $group->description); + return $ok; + } + + /** + * Redirect on successful remote group join + */ + function success() + { + $cur = common_current_user(); + $url = common_local_url('usergroups', array('nickname' => $cur->nickname)); + common_redirect($url, 303); + } + + /** + * Attempt to finalize subscription. + * validateFeed must have been run first. + * + * Calls showForm on failure or success on success. + */ + function saveFeed() + { + $user = common_current_user(); + $group = $this->oprofile->localGroup(); + if ($user->isMember($group)) { + // TRANS: OStatus remote group subscription dialog error. + $this->showForm(_m('Already a member!')); + return; + } + + if (Event::handle('StartJoinGroup', array($group, $user))) { + $ok = Group_member::join($this->oprofile->group_id, $user->id); + if ($ok) { + Event::handle('EndJoinGroup', array($group, $user)); + $this->success(); + } else { + // TRANS: OStatus remote group subscription dialog error. + $this->showForm(_m('Remote group join failed!')); + } + } else { + // TRANS: OStatus remote group subscription dialog error. + $this->showForm(_m('Remote group join aborted!')); + } + } + + /** + * Title of the page + * + * @return string Title of the page + */ + + function title() + { + // TRANS: Page title for OStatus remote group join form + return _m('Confirm joining remote group'); + } + + /** + * Instructions for use + * + * @return instructions for use + */ + + function getInstructions() + { + return _m('You can subscribe to groups from other supported sites. Paste the group\'s profile URI below:'); + } + + function selfLink() + { + return common_local_url('ostatusgroup'); + } +} diff --git a/plugins/OStatus/actions/ostatussub.php b/plugins/OStatus/actions/ostatussub.php index e318701a2..542f7e20c 100644 --- a/plugins/OStatus/actions/ostatussub.php +++ b/plugins/OStatus/actions/ostatussub.php @@ -1,7 +1,7 @@ elementStart('form', array('method' => 'post', 'id' => 'form_ostatus_sub', 'class' => 'form_settings', - 'action' => - common_local_url('ostatussub'))); + 'action' => $this->selfLink())); $this->hidden('token', common_session_token()); @@ -87,11 +84,7 @@ class OStatusSubAction extends Action */ function showPreviewForm() { - if ($this->oprofile->isGroup()) { - $ok = $this->previewGroup(); - } else { - $ok = $this->previewUser(); - } + $ok = $this->preview(); if (!$ok) { // @fixme maybe provide a cancel button or link back? return; @@ -104,7 +97,7 @@ class OStatusSubAction extends Action 'id' => 'form_ostatus_sub', 'class' => 'form_remote_authorize', 'action' => - common_local_url('ostatussub'))); + $this->selfLink())); $this->elementStart('fieldset'); $this->hidden('token', common_session_token()); $this->hidden('profile', $this->profile_uri); @@ -126,7 +119,7 @@ class OStatusSubAction extends Action * Show a preview for a remote user's profile * @return boolean true if we're ok to try subscribing */ - function previewUser() + function preview() { $oprofile = $this->oprofile; $profile = $oprofile->localProfile(); @@ -150,32 +143,6 @@ class OStatusSubAction extends Action return $ok; } - /** - * Show a preview for a remote group's profile - * @return boolean true if we're ok to try joining - */ - function previewGroup() - { - $oprofile = $this->oprofile; - $group = $oprofile->localGroup(); - - $cur = common_current_user(); - if ($cur->isMember($group)) { - $this->element('div', array('class' => 'error'), - _m("You are already a member of this group.")); - $ok = false; - } else { - $ok = true; - } - - $this->showEntity($group, - $group->getProfileUrl(), - $group->homepage_logo, - $group->description); - return $ok; - } - - function showEntity($entity, $profile, $avatar, $note) { $nickname = $entity->nickname; @@ -254,23 +221,13 @@ class OStatusSubAction extends Action /** * Redirect on successful remote user subscription */ - function successUser() + function success() { $cur = common_current_user(); $url = common_local_url('subscriptions', array('nickname' => $cur->nickname)); common_redirect($url, 303); } - /** - * Redirect on successful remote group join - */ - function successGroup() - { - $cur = common_current_user(); - $url = common_local_url('usergroups', array('nickname' => $cur->nickname)); - common_redirect($url, 303); - } - /** * Pull data for a remote profile and check if it's valid. * Fills out error UI string in $this->error @@ -278,16 +235,9 @@ class OStatusSubAction extends Action * * @return boolean */ - function validateFeed() + function pullRemoteProfile() { - $profile_uri = trim($this->arg('profile')); - - if ($profile_uri == '') { - $this->showForm(_m('Empty remote profile URL!')); - return; - } - $this->profile_uri = $profile_uri; - + $this->profile_uri = $this->trimmed('profile'); try { if (Validate::email($this->profile_uri)) { $this->oprofile = Ostatus_profile::ensureWebfinger($this->profile_uri); @@ -318,48 +268,34 @@ class OStatusSubAction extends Action return false; } + function validateRemoteProfile() + { + if ($this->oprofile->isGroup()) { + // Send us to the group subscription form for conf + $target = common_local_url('ostatusgroup', array(), array('profile' => $this->profile_uri)); + common_redirect($target, 303); + } + } + /** * Attempt to finalize subscription. * validateFeed must have been run first. * - * Calls showForm on failure or successUser/successGroup on success. + * Calls showForm on failure or success on success. */ function saveFeed() { // And subscribe the current user to the local profile $user = common_current_user(); - - if ($this->oprofile->isGroup()) { - $group = $this->oprofile->localGroup(); - if ($user->isMember($group)) { - // TRANS: OStatus remote group subscription dialog error. - $this->showForm(_m('Already a member!')); - return; - } - if (Event::handle('StartJoinGroup', array($group, $user))) { - $ok = Group_member::join($this->oprofile->group_id, $user->id); - if ($ok) { - Event::handle('EndJoinGroup', array($group, $user)); - $this->successGroup(); - } else { - // TRANS: OStatus remote group subscription dialog error. - $this->showForm(_m('Remote group join failed!')); - } - } else { - // TRANS: OStatus remote group subscription dialog error. - $this->showForm(_m('Remote group join aborted!')); - } + $local = $this->oprofile->localProfile(); + if ($user->isSubscribed($local)) { + // TRANS: OStatus remote subscription dialog error. + $this->showForm(_m('Already subscribed!')); + } elseif ($this->oprofile->subscribeLocalToRemote($user)) { + $this->success(); } else { - $local = $this->oprofile->localProfile(); - if ($user->isSubscribed($local)) { - // TRANS: OStatus remote subscription dialog error. - $this->showForm(_m('Already subscribed!')); - } elseif ($this->oprofile->subscribeLocalToRemote($user)) { - $this->successUser(); - } else { - // TRANS: OStatus remote subscription dialog error. - $this->showForm(_m('Remote subscription failed!')); - } + // TRANS: OStatus remote subscription dialog error. + $this->showForm(_m('Remote subscription failed!')); } } @@ -376,7 +312,9 @@ class OStatusSubAction extends Action return false; } - $this->profile_uri = $this->arg('profile'); + if ($this->pullRemoteProfile()) { + $this->validateRemoteProfile(); + } return true; } @@ -390,9 +328,6 @@ class OStatusSubAction extends Action if ($_SERVER['REQUEST_METHOD'] == 'POST') { $this->handlePost(); } else { - if ($this->arg('profile')) { - $this->validateFeed(); - } $this->showForm(); } } @@ -414,7 +349,7 @@ class OStatusSubAction extends Action return; } - if ($this->validateFeed()) { + if ($this->oprofile) { if ($this->arg('submit')) { $this->saveFeed(); return; @@ -500,4 +435,9 @@ class OStatusSubAction extends Action parent::showScripts(); $this->autofocus('feedurl'); } + + function selfLink() + { + return common_local_url('ostatussub'); + } } -- cgit v1.2.3-54-g00ecf From 6a5a629afac881fdc8369dfef2924f7f62949fab Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Wed, 3 Mar 2010 20:08:55 -0500 Subject: Updated label and note text for user and group remote subscribe forms --- plugins/OStatus/actions/ostatusgroup.php | 4 ++-- plugins/OStatus/actions/ostatussub.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'plugins/OStatus/actions/ostatussub.php') diff --git a/plugins/OStatus/actions/ostatusgroup.php b/plugins/OStatus/actions/ostatusgroup.php index 4fcd0eb39..f325ba053 100644 --- a/plugins/OStatus/actions/ostatusgroup.php +++ b/plugins/OStatus/actions/ostatusgroup.php @@ -72,9 +72,9 @@ class OStatusGroupAction extends OStatusSubAction $this->elementStart('ul', 'form_data'); $this->elementStart('li'); $this->input('profile', - _m('Group profile URL'), + _m('Join group'), $this->profile_uri, - _m('Enter the profile URL of a group on another StatusNet site')); + _m("OStatus group's address, like http://example.net/group/nickname")); $this->elementEnd('li'); $this->elementEnd('ul'); diff --git a/plugins/OStatus/actions/ostatussub.php b/plugins/OStatus/actions/ostatussub.php index 542f7e20c..7ca8a7869 100644 --- a/plugins/OStatus/actions/ostatussub.php +++ b/plugins/OStatus/actions/ostatussub.php @@ -62,9 +62,9 @@ class OStatusSubAction extends Action $this->elementStart('ul', 'form_data'); $this->elementStart('li'); $this->input('profile', - _m('Address or profile URL'), + _m('Subscribe to'), $this->profile_uri, - _m('Enter the profile URL of a PubSubHubbub-enabled feed')); + _m("OStatus user's address, like nickname@example.com or http://example.net/user/nickname")); $this->elementEnd('li'); $this->elementEnd('ul'); -- cgit v1.2.3-54-g00ecf From a4d9171306a06983094fdc90dbf040335c4f803f Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Wed, 3 Mar 2010 18:23:28 -0800 Subject: Fix up catching of webfinger setup fails --- plugins/OStatus/actions/ostatussub.php | 3 +-- plugins/OStatus/classes/Ostatus_profile.php | 13 ++++++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) (limited to 'plugins/OStatus/actions/ostatussub.php') diff --git a/plugins/OStatus/actions/ostatussub.php b/plugins/OStatus/actions/ostatussub.php index 7ca8a7869..e8a2c78ae 100644 --- a/plugins/OStatus/actions/ostatussub.php +++ b/plugins/OStatus/actions/ostatussub.php @@ -260,7 +260,7 @@ class OStatusSubAction extends Action $this->error = _m('Could not find a feed linked from this URL.'); } catch (FeedSubUnrecognizedTypeException $e) { $this->error = _m('Not a recognized feed type.'); - } catch (FeedSubException $e) { + } catch (Exception $e) { // Any new ones we forgot about $this->error = sprintf(_m('Bad feed URL: %s %s'), get_class($e), $e->getMessage()); } @@ -315,7 +315,6 @@ class OStatusSubAction extends Action if ($this->pullRemoteProfile()) { $this->validateRemoteProfile(); } - return true; } diff --git a/plugins/OStatus/classes/Ostatus_profile.php b/plugins/OStatus/classes/Ostatus_profile.php index 7ab031aa5..b3b4336b5 100644 --- a/plugins/OStatus/classes/Ostatus_profile.php +++ b/plugins/OStatus/classes/Ostatus_profile.php @@ -1267,6 +1267,11 @@ class Ostatus_profile extends Memcached_DataObject } } + /** + * @param string $addr webfinger address + * @return Ostatus_profile + * @throws Exception on error conditions + */ public static function ensureWebfinger($addr) { // First, try the cache @@ -1275,7 +1280,8 @@ class Ostatus_profile extends Memcached_DataObject if ($uri !== false) { if (is_null($uri)) { - return null; + // Negative cache entry + throw new Exception('Not a valid webfinger address.'); } $oprofile = Ostatus_profile::staticGet('uri', $uri); if (!empty($oprofile)) { @@ -1299,8 +1305,9 @@ class Ostatus_profile extends Memcached_DataObject try { $result = $disco->lookup($addr); } catch (Exception $e) { + // Save negative cache entry so we don't waste time looking it up again. self::cacheSet(sprintf('ostatus_profile:webfinger:%s', $addr), null); - return null; + throw new Exception('Not a valid webfinger address.'); } foreach ($result->links as $link) { @@ -1410,7 +1417,7 @@ class Ostatus_profile extends Memcached_DataObject return $oprofile; } - return null; + throw new Exception("Couldn't find a valid profile for '$addr'"); } function saveHTMLFile($title, $rendered) -- cgit v1.2.3-54-g00ecf From de687d00c0ebe8bf5d185b7037df7f1edfd368a3 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Wed, 3 Mar 2010 22:56:50 -0500 Subject: Updated OStatus subscription error messages to be more user friendly. Hopefully. --- plugins/OStatus/actions/ostatussub.php | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'plugins/OStatus/actions/ostatussub.php') diff --git a/plugins/OStatus/actions/ostatussub.php b/plugins/OStatus/actions/ostatussub.php index e8a2c78ae..bee48a8ae 100644 --- a/plugins/OStatus/actions/ostatussub.php +++ b/plugins/OStatus/actions/ostatussub.php @@ -64,7 +64,7 @@ class OStatusSubAction extends Action $this->input('profile', _m('Subscribe to'), $this->profile_uri, - _m("OStatus user's address, like nickname@example.com or http://example.net/user/nickname")); + _m("OStatus user's address, like nickname@example.com or http://example.net/nickname")); $this->elementEnd('li'); $this->elementEnd('ul'); @@ -244,25 +244,33 @@ class OStatusSubAction extends Action } else if (Validate::uri($this->profile_uri)) { $this->oprofile = Ostatus_profile::ensureProfile($this->profile_uri); } else { - $this->error = _m("Invalid address format."); + $this->error = _m("Sorry, we could not reach that address. Please make sure that the OStatus address is like nickname@example.com or http://example.net/nickname"); + common_debug('Invalid address format.', __FILE__); return false; } return true; } catch (FeedSubBadURLException $e) { - $this->error = _m('Invalid URL or could not reach server.'); + $this->error = _m("Sorry, we could not reach that address. Please make sure that the OStatus address is like nickname@example.com or http://example.net/nickname"); + common_debug('Invalid URL or could not reach server.', __FILE__); } catch (FeedSubBadResponseException $e) { - $this->error = _m('Cannot read feed; server returned error.'); + $this->error = _m("Sorry, we could not reach that feed. Please try that OStatus address again later."); + common_debug('Cannot read feed; server returned error.', __FILE__); } catch (FeedSubEmptyException $e) { - $this->error = _m('Cannot read feed; server returned an empty page.'); + $this->error = _m("Sorry, we could not reach that feed. Please try that OStatus address again later."); + common_debug('Cannot read feed; server returned an empty page.', __FILE__); } catch (FeedSubBadHTMLException $e) { - $this->error = _m('Bad HTML, could not find feed link.'); + $this->error = _m("Sorry, we could not reach that feed. Please try that OStatus address again later."); + common_debug('Bad HTML, could not find feed link.', __FILE__); } catch (FeedSubNoFeedException $e) { - $this->error = _m('Could not find a feed linked from this URL.'); + $this->error = _m("Sorry, we could not reach that feed. Please try that OStatus address again later."); + common_debug('Could not find a feed linked from this URL.', __FILE__); } catch (FeedSubUnrecognizedTypeException $e) { - $this->error = _m('Not a recognized feed type.'); + $this->error = _m("Sorry, we could not reach that feed. Please try that OStatus address again later."); + common_debug('Not a recognized feed type.', __FILE__); } catch (Exception $e) { // Any new ones we forgot about - $this->error = sprintf(_m('Bad feed URL: %s %s'), get_class($e), $e->getMessage()); + $this->error = _m("Sorry, we could not reach that address. Please make sure that the OStatus address is like nickname@example.com or http://example.net/nickname"); + common_debug(sprintf('Bad feed URL: %s %s', get_class($e), $e->getMessage()), __FILE__); } return false; -- cgit v1.2.3-54-g00ecf From b97ac60209fdec3f2d521f7c9d54acca6d00d274 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Wed, 3 Mar 2010 23:47:27 -0500 Subject: Changed text for authorizing/confirming remote profile --- plugins/OStatus/actions/ostatussub.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins/OStatus/actions/ostatussub.php') diff --git a/plugins/OStatus/actions/ostatussub.php b/plugins/OStatus/actions/ostatussub.php index bee48a8ae..65dee2392 100644 --- a/plugins/OStatus/actions/ostatussub.php +++ b/plugins/OStatus/actions/ostatussub.php @@ -398,7 +398,7 @@ class OStatusSubAction extends Action function title() { // TRANS: Page title for OStatus remote subscription form - return _m('Authorize subscription'); + return _m('Confirm'); } /** -- cgit v1.2.3-54-g00ecf