summaryrefslogtreecommitdiff
path: root/plugins/OStatus
diff options
context:
space:
mode:
authorBrion Vibber <brion@pobox.com>2010-02-23 20:44:27 +0000
committerBrion Vibber <brion@pobox.com>2010-02-23 20:44:27 +0000
commit90d34b26c66ceb5d37a9c2782356b46361a523cc (patch)
tree2882722b42779e468bcf8ab2d074d506a5ee2f52 /plugins/OStatus
parentc79c70ea2c2dadafa72c65dc4593a66fecb070e3 (diff)
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.
Diffstat (limited to 'plugins/OStatus')
-rw-r--r--plugins/OStatus/OStatusPlugin.php158
-rw-r--r--plugins/OStatus/actions/ostatussub.php5
-rw-r--r--plugins/OStatus/classes/Ostatus_profile.php26
3 files changed, 124 insertions, 65 deletions
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
@@ -252,58 +252,6 @@ class OStatusPlugin extends Plugin
}
/**
- * 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.
*/
function onCheckSchema() {
@@ -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);
@@ -404,6 +396,54 @@ class OStatusPlugin extends Plugin
}
/**
+ * 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,
* deny the join.
@@ -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
@@ -347,6 +347,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);