Ostatus_profile throws NoProfileException from localProfile()

Some implementations of the exception handling is included here,
the actions come in a later commit.
This commit is contained in:
Mikael Nordfeldth 2014-05-19 17:58:05 +02:00
parent d2c749c7de
commit 228dc1f851
6 changed files with 86 additions and 42 deletions

View File

@ -423,7 +423,12 @@ class OStatusPlugin extends Plugin
{ {
$oprofile = $this->pullRemoteProfile($arg); $oprofile = $this->pullRemoteProfile($arg);
if ($oprofile instanceof Ostatus_profile && !$oprofile->isGroup()) { if ($oprofile instanceof Ostatus_profile && !$oprofile->isGroup()) {
$profile = $oprofile->localProfile(); try {
$profile = $oprofile->localProfile();
} catch (NoProfileException $e) {
// No locally stored profile found for remote profile
return true;
}
return false; return false;
} else { } else {
return true; return true;

View File

@ -264,6 +264,7 @@ class FeedSub extends Managed_DataObject
* make sure it's inactive, unsubscribing if necessary. * make sure it's inactive, unsubscribing if necessary.
* *
* @return boolean true if the subscription is now inactive, false if still active. * @return boolean true if the subscription is now inactive, false if still active.
* @throws NoProfileException in FeedSubSubscriberCount for missing Profile entries
* @throws Exception if something goes wrong in unsubscribe() method * @throws Exception if something goes wrong in unsubscribe() method
*/ */
public function garbageCollect() public function garbageCollect()
@ -271,22 +272,23 @@ class FeedSub extends Managed_DataObject
if ($this->sub_state == '' || $this->sub_state == 'inactive') { if ($this->sub_state == '' || $this->sub_state == 'inactive') {
// No active PuSH subscription, we can just leave it be. // No active PuSH subscription, we can just leave it be.
return true; return true;
} else {
// PuSH subscription is either active or in an indeterminate state.
// Check if we're out of subscribers, and if so send an unsubscribe.
$count = 0;
Event::handle('FeedSubSubscriberCount', array($this, &$count));
if ($count > 0) {
common_log(LOG_INFO, __METHOD__ . ': ok, ' . $count . ' user(s) left for ' . $this->getUri());
return false;
} else {
common_log(LOG_INFO, __METHOD__ . ': unsubscribing, no users left for ' . $this->getUri());
// Unsubscribe throws various Exceptions on failure
$this->unsubscribe();
return true;
}
} }
// PuSH subscription is either active or in an indeterminate state.
// Check if we're out of subscribers, and if so send an unsubscribe.
$count = 0;
Event::handle('FeedSubSubscriberCount', array($this, &$count));
if ($count > 0) {
common_log(LOG_INFO, __METHOD__ . ': ok, ' . $count . ' user(s) left for ' . $this->getUri());
return false;
}
common_log(LOG_INFO, __METHOD__ . ': unsubscribing, no users left for ' . $this->getUri());
// Unsubscribe throws various Exceptions on failure
$this->unsubscribe();
return true;
} }
static public function renewalCheck() static public function renewalCheck()
@ -505,4 +507,18 @@ class FeedSub extends Managed_DataObject
} }
return false; return false;
} }
public function delete($useWhere=false)
{
try {
$oprofile = Ostatus_profile::getKV('feeduri', $this->getUri());
$profile = $oprofile->localProfile();
} catch (NoProfileException $e) {
// If the Ostatus_profile has no local Profile bound to it, let's clean it out at the same time
$oprofile->delete();
} catch (NoUriException $e) {
// FeedSub->getUri() can throw a NoUriException, let's just go ahead and delete it
}
return parent::delete($useWhere);
}
} }

View File

@ -63,10 +63,10 @@ class Ostatus_profile extends Managed_DataObject
), ),
'primary key' => array('uri'), 'primary key' => array('uri'),
'unique keys' => array( 'unique keys' => array(
'ostatus_profile_profile_id_idx' => array('profile_id'), 'ostatus_profile_profile_id_key' => array('profile_id'),
'ostatus_profile_group_id_idx' => array('group_id'), 'ostatus_profile_group_id_key' => array('group_id'),
'ostatus_profile_peopletag_id_idx' => array('peopletag_id'), 'ostatus_profile_peopletag_id_key' => array('peopletag_id'),
'ostatus_profile_feeduri_idx' => array('feeduri'), 'ostatus_profile_feeduri_key' => array('feeduri'),
), ),
'foreign keys' => array( 'foreign keys' => array(
'ostatus_profile_profile_id_fkey' => array('profile', array('profile_id' => 'id')), 'ostatus_profile_profile_id_fkey' => array('profile', array('profile_id' => 'id')),
@ -82,15 +82,17 @@ class Ostatus_profile extends Managed_DataObject
} }
/** /**
* Fetch the StatusNet-side profile for this feed * Fetch the locally stored profile for this feed
* @return Profile * @return Profile
* @throws NoProfileException if it was not found
*/ */
public function localProfile() public function localProfile()
{ {
if ($this->profile_id) { $profile = Profile::getKV('id', $this->profile_id);
return Profile::getKV('id', $this->profile_id); if ($profile instanceof Profile) {
return $profile;
} }
return null; throw new NoProfileException($this->profile_id);
} }
/** /**
@ -247,6 +249,7 @@ class Ostatus_profile extends Managed_DataObject
* FeedSub::garbageCollect(). * FeedSub::garbageCollect().
* *
* @return int * @return int
* @throws NoProfileException if there is no local profile for the object
*/ */
public function subscriberCount() public function subscriberCount()
{ {
@ -258,9 +261,10 @@ class Ostatus_profile extends Managed_DataObject
$count = $subscribers->N; $count = $subscribers->N;
} else { } else {
$profile = $this->localProfile(); $profile = $this->localProfile();
$count = $profile->subscriberCount();
if ($profile->hasLocalTags()) { if ($profile->hasLocalTags()) {
$count = 1; $count = 1;
} else {
$count = $profile->subscriberCount();
} }
} }
common_log(LOG_INFO, __METHOD__ . " SUB COUNT BEFORE: $count"); common_log(LOG_INFO, __METHOD__ . " SUB COUNT BEFORE: $count");
@ -940,12 +944,16 @@ class Ostatus_profile extends Managed_DataObject
if ($id) { if ($id) {
$group = User_group::getKV('id', $id); $group = User_group::getKV('id', $id);
if ($group instanceof User_group) { if ($group instanceof User_group) {
// Deliver to all members of this local group if allowed. try {
$profile = $sender->localProfile(); // Deliver to all members of this local group if allowed.
if ($profile->isMember($group)) { $profile = $sender->localProfile();
$groups[] = $group->id; if ($profile->isMember($group)) {
} else { $groups[] = $group->id;
common_log(LOG_DEBUG, "Skipping reply to local group $group->nickname as sender $profile->id is not a member"); } else {
common_log(LOG_DEBUG, "Skipping reply to local group $group->nickname as sender $profile->id is not a member");
}
} catch (NoProfileException $e) {
// Sender has no profile! Do some garbage collection, please.
} }
continue; continue;
} else { } else {
@ -1227,8 +1235,10 @@ class Ostatus_profile extends Managed_DataObject
} }
if ($this->isGroup()) { if ($this->isGroup()) {
// FIXME: throw exception for localGroup
$self = $this->localGroup(); $self = $this->localGroup();
} else { } else {
// this throws an exception already
$self = $this->localProfile(); $self = $this->localProfile();
} }
if (!$self) { if (!$self) {

View File

@ -31,13 +31,22 @@ require_once INSTALLDIR.'/scripts/commandline.inc';
$feedsub = new FeedSub(); $feedsub = new FeedSub();
$feedsub->find(); $feedsub->find();
while ($feedsub->fetch()) { while ($feedsub->fetch()) {
echo "{$feedsub->uri} ({$feedsub->sub_state})";
try { try {
echo $feedsub->getUri() . " ({$feedsub->sub_state})";
if ($feedsub->garbageCollect()) { if ($feedsub->garbageCollect()) {
echo " INACTIVE\n"; echo " INACTIVE\n";
} else { } else {
echo " ACTIVE\n"; echo " ACTIVE\n";
} }
} catch (NoProfileException $e) {
echo " DELETED (no profile)\n";
$feedsub->delete();
continue;
} catch (NoUriException $e) {
// Probably the getUri() call
echo "[unknown] DELETED (no uri)\n";
$feedsub->delete();
continue;
} catch (Exception $e) { } catch (Exception $e) {
echo " ERROR: {$e->getMessage()}\n"; echo " ERROR: {$e->getMessage()}\n";
} }

View File

@ -38,13 +38,17 @@ END_OF_HELP;
require_once INSTALLDIR.'/scripts/commandline.inc'; require_once INSTALLDIR.'/scripts/commandline.inc';
function showProfileInfo($oprofile) { function showProfileInfo(Ostatus_profile $oprofile) {
if ($oprofile->isGroup()) { if ($oprofile->isGroup()) {
echo "group\n"; echo "group\n";
} else { } else {
$profile = $oprofile->localProfile(); $profile = $oprofile->localProfile();
foreach (array('nickname', 'bio', 'homepage', 'location') as $field) { try {
print " $field: {$profile->$field}\n"; foreach (array('nickname', 'bio', 'homepage', 'location') as $field) {
print " $field: {$profile->$field}\n";
}
} catch (NoProfileException $e) {
print "local profile not found";
} }
} }
echo "\n"; echo "\n";

View File

@ -129,20 +129,20 @@ class SubMirrorPlugin extends Plugin
* @param int $count in/out * @param int $count in/out
* @return mixed hook return value * @return mixed hook return value
*/ */
function onOstatus_profileSubscriberCount($oprofile, &$count) function onOstatus_profileSubscriberCount(Ostatus_profile $oprofile, &$count)
{ {
if (empty($oprofile) || !($oprofile instanceof Ostatus_profile)) { try {
return true; $profile = $oprofile->localProfile();
}
if ($oprofile->profile_id) {
$mirror = new SubMirror(); $mirror = new SubMirror();
$mirror->subscribed = $oprofile->profile_id; $mirror->subscribed = $profile->id;
if ($mirror->find()) { if ($mirror->find()) {
while ($mirror->fetch()) { while ($mirror->fetch()) {
$count++; $count++;
} }
} }
} catch (NoProfileException $e) {
// We can't handle this kind of Ostatus_profile since it has no
// local profile
} }
return true; return true;