Example #1
0
 public function checkUpdates(FeedSub $feedsub)
 {
     $request = new HTTPClient();
     $feed = $request->get($feedsub->uri);
     if (!$feed->isOk()) {
         throw new ServerException('FeedSub could not fetch id=' . $feedsub->id . ' (Error ' . $feed->getStatus() . ': ' . $feed->getBody());
     }
     $feedsub->receive($feed->getBody(), null);
 }
 public function onFeedUnsubscribe(FeedSub $feedsub)
 {
     if (!$feedsub->isPuSH()) {
         // removes sub_state setting and such
         $feedsub->confirmUnsubscribe();
         return false;
     }
     return true;
 }
 function handle($data)
 {
     $feedsub_id = $data['feedsub_id'];
     $feedsub = FeedSub::getKV('id', $feedsub_id);
     if ($feedsub instanceof FeedSub) {
         try {
             common_log(LOG_INFO, "Renewing feed subscription\n\tExp.: {$feedsub->sub_end}\n\tFeed: {$feedsub->uri}\n\tHub:  {$feedsub->huburi}");
             $feedsub->renew();
         } catch (Exception $e) {
             common_log(LOG_ERR, "Exception during PuSH renew processing for {$feedsub->uri}: " . $e->getMessage());
         }
     } else {
         common_log(LOG_ERR, "Discarding renew for unknown feed subscription id {$feedsub_id}");
     }
     return true;
 }
Example #4
0
 /**
  * Handler for GET verification requests from the hub.
  */
 function handleGet()
 {
     $mode = $this->arg('hub_mode');
     $topic = $this->arg('hub_topic');
     $challenge = $this->arg('hub_challenge');
     $lease_seconds = $this->arg('hub_lease_seconds');
     $verify_token = $this->arg('hub_verify_token');
     common_log(LOG_INFO, __METHOD__ . ": sub verification mode: {$mode} topic: {$topic} challenge: {$challenge} lease_seconds: {$lease_seconds} verify_token: {$verify_token}");
     if ($mode != 'subscribe' && $mode != 'unsubscribe') {
         // TRANS: Client exception. %s is an invalid value for hub.mode.
         throw new ClientException(sprintf(_m('Bad hub.mode "$s".', $mode)), 404);
     }
     $feedsub = FeedSub::staticGet('uri', $topic);
     if (!$feedsub) {
         // TRANS: Client exception. %s is an invalid feed name.
         throw new ClientException(sprintf(_m('Bad hub.topic feed "%s".'), $topic), 404);
     }
     if ($feedsub->verify_token !== $verify_token) {
         // TRANS: Client exception. %1$s the invalid token, %2$s is the topic for which the invalid token was given.
         throw new ClientException(sprintf(_m('Bad hub.verify_token %1$s for %2$s.'), $token, $topic), 404);
     }
     if ($mode == 'subscribe') {
         // We may get re-sub requests legitimately.
         if ($feedsub->sub_state != 'subscribe' && $feedsub->sub_state != 'active') {
             // TRANS: Client exception. %s is an invalid topic.
             throw new ClientException(sprintf(_m('Unexpected subscribe request for %s.'), $topic), 404);
         }
     } else {
         if ($feedsub->sub_state != 'unsubscribe') {
             // TRANS: Client exception. %s is an invalid topic.
             throw new ClientException(sprintf(_m('Unexpected unsubscribe request for %s.'), $topic), 404);
         }
     }
     if ($mode == 'subscribe') {
         if ($feedsub->sub_state == 'active') {
             common_log(LOG_INFO, __METHOD__ . ': sub update confirmed');
         } else {
             common_log(LOG_INFO, __METHOD__ . ': sub confirmed');
         }
         $feedsub->confirmSubscribe($lease_seconds);
     } else {
         common_log(LOG_INFO, __METHOD__ . ": unsub confirmed; deleting sub record for {$topic}");
         $feedsub->confirmUnsubscribe();
     }
     print $challenge;
 }
 public function handle($item)
 {
     $feedsub = FeedSub::getKV('id', $item['id']);
     if (!$feedsub instanceof FeedSub) {
         // Removed from the feedsub table I guess
         return true;
     }
     if (!$feedsub->sub_state == 'nohub') {
         // We're not supposed to poll this (either it's PuSH or it's unsubscribed)
         return true;
     }
     try {
         FeedPoll::checkUpdates($feedsub);
     } catch (Exception $e) {
         common_log(LOG_ERR, "Failed to check feedsub id= " . $feedsub->id . ' ("' . $e->getMessage() . '")');
     }
     return true;
 }
 function handle($data)
 {
     assert(is_array($data));
     $feedsub_id = $data['feedsub_id'];
     $post = $data['post'];
     $hmac = $data['hmac'];
     $feedsub = FeedSub::staticGet('id', $feedsub_id);
     if ($feedsub) {
         try {
             $feedsub->receive($post, $hmac);
         } catch (Exception $e) {
             common_log(LOG_ERR, "Exception during PuSH input processing for {$feedsub->uri}: " . $e->getMessage());
         }
     } else {
         common_log(LOG_ERR, "Discarding POST to unknown feed subscription id {$feedsub_id}");
     }
     return true;
 }
Example #7
0
 /**
  * Handler for GET verification requests from the hub.
  */
 function handleGet()
 {
     $mode = $this->arg('hub_mode');
     $topic = $this->arg('hub_topic');
     $challenge = $this->arg('hub_challenge');
     $lease_seconds = $this->arg('hub_lease_seconds');
     $verify_token = $this->arg('hub_verify_token');
     if ($mode != 'subscribe' && $mode != 'unsubscribe') {
         throw new ClientException("Bad hub.mode {$mode}", 404);
     }
     $feedsub = FeedSub::staticGet('uri', $topic);
     if (!$feedsub) {
         // @todo i18n FIXME: added i18n and use sprintf when using parameters.
         throw new ClientException("Bad hub.topic feed {$topic}.", 404);
     }
     if ($feedsub->verify_token !== $verify_token) {
         // @todo i18n FIXME: added i18n and use sprintf when using parameters.
         throw new ClientException("Bad hub.verify_token {$token} for {$topic}.", 404);
     }
     if ($mode == 'subscribe') {
         // We may get re-sub requests legitimately.
         if ($feedsub->sub_state != 'subscribe' && $feedsub->sub_state != 'active') {
             // @todo i18n FIXME: added i18n and use sprintf when using parameters.
             throw new ClientException("Unexpected subscribe request for {$topic}.", 404);
         }
     } else {
         if ($feedsub->sub_state != 'unsubscribe') {
             // @todo i18n FIXME: added i18n and use sprintf when using parameters.
             throw new ClientException("Unexpected unsubscribe request for {$topic}.", 404);
         }
     }
     if ($mode == 'subscribe') {
         if ($feedsub->sub_state == 'active') {
             common_log(LOG_INFO, __METHOD__ . ': sub update confirmed');
         } else {
             common_log(LOG_INFO, __METHOD__ . ': sub confirmed');
         }
         $feedsub->confirmSubscribe($lease_seconds);
     } else {
         common_log(LOG_INFO, __METHOD__ . ": unsub confirmed; deleting sub record for {$topic}");
         $feedsub->confirmUnsubscribe();
     }
     print $challenge;
 }
 public function onCronDaily()
 {
     try {
         $sub = FeedSub::renewalCheck();
     } catch (NoResultException $e) {
         common_log(LOG_INFO, "There were no expiring feeds.");
         return;
     }
     $qm = QueueManager::get();
     while ($sub->fetch()) {
         $item = array('feedsub_id' => $sub->id);
         $qm->enqueue($item, 'pushrenew');
     }
 }
Example #9
0
Mainly intended for testing funky feed formats.

     --skip=N   Ignore the first N items in the feed.
     --count=N  Only process up to N items from the feed, after skipping.


END_OF_HELP;
require_once INSTALLDIR . '/scripts/commandline.inc';
if (empty($args[0]) || !Validate::uri($args[0])) {
    print "{$helptext}";
    exit(1);
}
$feedurl = $args[0];
$skip = have_option('skip') ? intval(get_option_value('skip')) : 0;
$count = have_option('count') ? intval(get_option_value('count')) : 0;
$sub = FeedSub::staticGet('uri', $feedurl);
if (!$sub) {
    print "Feed {$feedurl} is not subscribed.\n";
    exit(1);
}
$xml = file_get_contents($feedurl);
if ($xml === false) {
    print "Bad fetch.\n";
    exit(1);
}
$feed = new DOMDocument();
if (!$feed->loadXML($xml)) {
    print "Bad XML.\n";
    exit(1);
}
if ($skip || $count) {
Example #10
0
     --skip=N   Ignore the first N items in the feed.
     --count=N  Only process up to N items from the feed, after skipping.


END_OF_HELP;
require_once INSTALLDIR . '/scripts/commandline.inc';
$validate = new Validate();
if (empty($args[0]) || !$validate->uri($args[0])) {
    print "{$helptext}";
    exit(1);
}
$feedurl = $args[0];
$skip = have_option('skip') ? intval(get_option_value('skip')) : 0;
$count = have_option('count') ? intval(get_option_value('count')) : 0;
$sub = FeedSub::getKV('uri', $feedurl);
if (!$sub) {
    print "Feed {$feedurl} is not subscribed.\n";
    exit(1);
}
// Fetch the URL
try {
    $xml = HTTPClient::quickGet($feedurl, 'text/html,application/xhtml+xml');
} catch (Exception $e) {
    echo sprintf("Could not fetch feedurl %s (%d).\n", $e->getMessage(), $e->getCode());
    exit(1);
}
$feed = new DOMDocument();
if (!$feed->loadXML($xml)) {
    print "Bad XML.\n";
    exit(1);
Example #11
0
 /**
  * Check if this remote profile has any active local subscriptions, and
  * if not drop the PuSH subscription feed.
  *
  * @return boolean
  */
 public function garbageCollect()
 {
     $feedsub = FeedSub::staticGet('uri', $this->feeduri);
     return $feedsub->garbageCollect();
 }
 /**
  * Make sure necessary tables are filled out.
  */
 function onCheckSchema()
 {
     $schema = Schema::get();
     $schema->ensureTable('ostatus_profile', Ostatus_profile::schemaDef());
     $schema->ensureTable('ostatus_source', Ostatus_source::schemaDef());
     $schema->ensureTable('feedsub', FeedSub::schemaDef());
     $schema->ensureTable('hubsub', HubSub::schemaDef());
     $schema->ensureTable('magicsig', Magicsig::schemaDef());
     return true;
 }
Example #13
0
 /**
  * Check if this remote profile has any active local subscriptions, and
  * if not drop the PuSH subscription feed.
  *
  * @return boolean true if subscription is removed, false if there are still subscribers to the feed
  * @throws Exception of various kinds on failure.
  */
 public function garbageCollect()
 {
     $feedsub = FeedSub::getKV('uri', $this->feeduri);
     if ($feedsub instanceof FeedSub) {
         return $feedsub->garbageCollect();
     }
     // Since there's no FeedSub we can assume it's already garbage collected
     return true;
 }
Example #14
0
 public function updateUriKeys($profile_uri, array $hints = array())
 {
     $orig = clone $this;
     common_debug('URIFIX These identities both say they are each other: "' . $orig->uri . '" and "' . $profile_uri . '"');
     $this->uri = $profile_uri;
     if (array_key_exists('feedurl', $hints)) {
         if (!empty($this->feeduri)) {
             common_debug('URIFIX Changing FeedSub [' . $feedsub->id . '] feeduri "' . $feedsub->uri . '" to "' . $hints['feedurl']);
             $feedsub = FeedSub::getKV('uri', $this->feeduri);
             $feedorig = clone $feedsub;
             $feedsub->uri = $hints['feedurl'];
             $feedsub->updateWithKeys($feedorig);
         } else {
             common_debug('URIFIX Old Ostatus_profile did not have feedurl set, ensuring feed: ' . $hints['feedurl']);
             FeedSub::ensureFeed($hints['feedurl']);
         }
         $this->feeduri = $hints['feedurl'];
     }
     if (array_key_exists('salmon', $hints)) {
         common_debug('URIFIX Changing Ostatus_profile salmonuri from "' . $this->salmonuri . '" to "' . $hints['salmon'] . '"');
         $this->salmonuri = $hints['salmon'];
     }
     common_debug('URIFIX Updating Ostatus_profile URI for ' . $orig->uri . ' to ' . $this->uri);
     $this->updateWithKeys($orig, 'uri');
     // 'uri' is the primary key column
     common_debug('URIFIX Subscribing/renewing feedsub for Ostatus_profile ' . $this->uri);
     $this->subscribe();
 }
Example #15
0
 */
define('INSTALLDIR', realpath(dirname(__FILE__) . '/../../..'));
$helptext = <<<END_OF_HELP
pollfeed.php feeduri

Poll the feed, assuming it has sub_state 'nohub'.

END_OF_HELP;
require_once INSTALLDIR . '/scripts/commandline.inc';
require_once __DIR__ . '/../lib/feedpoll.php';
if (empty($args[0]) || !Validate::uri($args[0])) {
    echo "{$helptext}\n";
    exit(1);
}
$uri = $args[0];
$feedsub = FeedSub::getKV('uri', $uri);
if (!$feedsub instanceof FeedSub) {
    echo "No FeedSub feed known for URI {$uri}\n";
    exit(1);
}
if ($feedsub->sub_state != 'nohub') {
    echo "Feed is a PuSH feed, so we will not poll it.\n";
    exit(1);
}
showSub($feedsub);
try {
    FeedPoll::checkUpdates($feedsub);
} catch (Exception $e) {
    echo "Could not check updates for feed: " . $e->getMessage();
    echo $e->getTraceAsString();
    exit(1);
Example #16
0
}
print "\n";
print "Pinging hub {$sub->huburi} with new subscription for {$sub->uri}\n";
$ok = $sub->subscribe();
if ($ok) {
    print "ok\n";
} else {
    print "Could not confirm.\n";
}
$o2 = Ostatus_profile::staticGet('uri', $uri);
print "\n";
print "New profile state:\n";
showProfile($o2);
print "\n";
print "New feed state:\n";
$sub2 = FeedSub::ensureFeed($feedurl);
showSub($sub2);
function showProfile($oprofile)
{
    print "  Feed URL: {$oprofile->feeduri}\n";
    print "  Salmon URL: {$oprofile->salmonuri}\n";
    print "  Avatar URL: {$oprofile->avatar}\n";
    print "  Profile ID: {$oprofile->profile_id}\n";
    print "  Group ID: {$oprofile->group_id}\n";
    print "  Record created: {$oprofile->created}\n";
    print "  Record modified: {$oprofile->modified}\n";
}
function showSub($sub)
{
    print "  Subscription state: {$sub->sub_state}\n";
    print "  Verify token: {$sub->verify_token}\n";
and are older than one hour. If the hub hasn't answered back in an hour
the hub is probably either broken or doesn't exist.'

      Options:

    -d --dry-run look but don't mess with it


END_OF_HELP;
require_once INSTALLDIR . '/scripts/commandline.inc';
$dry = false;
if (have_option('d') || have_option('dry-run')) {
    $dry = true;
}
echo "Looking for feed subscriptions with dirty no good huburis...\n";
$feedsub = new FeedSub();
$feedsub->sub_state = 'subscribe';
$feedsub->whereAdd('created < DATE_SUB(NOW(), INTERVAL 1 HOUR)');
$feedsub->find();
$cnt = 0;
while ($feedsub->fetch()) {
    echo "----------------------------------------------------------------------------------------\n";
    echo '           feed: ' . $feedsub->uri . "\n" . '        hub uri: ' . $feedsub->huburi . "\n" . ' subscribe date: ' . date('r', strtotime($feedsub->created)) . "\n";
    if (!$dry) {
        $feedsub->delete();
        echo "                 (DELETED)\n";
    } else {
        echo "                 (WOULD BE DELETED)\n";
    }
    echo "----------------------------------------------------------------------------------------\n";
    $cnt++;
Example #18
0
 /**
  * @param string $feeduri
  * @return FeedSub
  * @throws FeedSubException if feed is invalid or lacks PuSH setup
  */
 public static function ensureFeed($feeduri)
 {
     $current = self::staticGet('uri', $feeduri);
     if ($current) {
         return $current;
     }
     $discover = new FeedDiscovery();
     $discover->discoverFromFeedURL($feeduri);
     $huburi = $discover->getHubLink();
     if (!$huburi && !common_config('feedsub', 'fallback_hub')) {
         throw new FeedSubNoHubException();
     }
     $feedsub = new FeedSub();
     $feedsub->uri = $feeduri;
     $feedsub->huburi = $huburi;
     $feedsub->sub_state = 'inactive';
     $feedsub->created = common_sql_now();
     $feedsub->modified = common_sql_now();
     $result = $feedsub->insert();
     if (empty($result)) {
         throw new FeedDBException($feedsub);
     }
     return $feedsub;
 }
Example #19
0
 public static function renewalCheck()
 {
     $fs = new FeedSub();
     // the "" empty string check is because we historically haven't saved unsubscribed feeds as NULL
     $fs->whereAdd('sub_end IS NOT NULL AND sub_end!="" AND sub_end < NOW() - INTERVAL 1 day');
     if (!$fs->find()) {
         // find can be both false and 0, depending on why nothing was found
         throw new NoResultException($fs);
     }
     return $fs;
 }
Example #20
0
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
define('INSTALLDIR', realpath(dirname(__FILE__) . '/../../..'));
$longoptions = array('delete-inactive');
$shortoptions = 'd';
$helptext = <<<END_OF_HELP
gcfeeds.php [options]
Clean up feeds that no longer have subscribers.

    -d --delete-inactive    Delete inactive feeds from feedsub table.

END_OF_HELP;
require_once INSTALLDIR . '/scripts/commandline.inc';
$delete_inactive = have_option('d', 'delete-inactive');
$delcount = 0;
$feedsub = new FeedSub();
$feedsub->find();
while ($feedsub->fetch()) {
    try {
        echo $feedsub->getUri() . " ({$feedsub->sub_state})";
        if ($feedsub->garbageCollect()) {
            if ($delete_inactive) {
                $delcount++;
                $feedsub->delete();
                echo " DELETED";
            }
            echo " INACTIVE\n";
        } else {
            echo " ACTIVE\n";
        }
    } catch (NoProfileException $e) {
Mainly intended for testing funky feed formats.

     --skip=N   Ignore the first N items in the feed.
     --count=N  Only process up to N items from the feed, after skipping.


END_OF_HELP;
require_once INSTALLDIR . '/scripts/commandline.inc';
if (empty($args[0]) || !Validate::uri($args[0])) {
    print "{$helptext}";
    exit(1);
}
$feedurl = $args[0];
$skip = have_option('skip') ? intval(get_option_value('skip')) : 0;
$count = have_option('count') ? intval(get_option_value('count')) : 0;
$sub = FeedSub::staticGet('topic', $feedurl);
if (!$sub) {
    print "Feed {$feedurl} is not subscribed.\n";
    exit(1);
}
$xml = file_get_contents($feedurl);
if ($xml === false) {
    print "Bad fetch.\n";
    exit(1);
}
$feed = new DOMDocument();
if (!$feed->loadXML($xml)) {
    print "Bad XML.\n";
    exit(1);
}
if ($skip || $count) {
 /**
  * Send a PuSH unsubscription request to the hub for this feed.
  * The hub will later send us a confirmation POST to /main/push/callback.
  *
  * @return bool true on success, false on failure
  * @throws ServerException if feed state is not valid
  */
 public function unsubscribe()
 {
     $feedsub = FeedSub::staticGet('uri', $this->feeduri);
     if (!$feedsub || $feedsub->sub_state == '' || $feedsub->sub_state == 'inactive') {
         // No active PuSH subscription, we can just leave it be.
         return true;
     } else {
         // PuSH subscription is either active or in an indeterminate state.
         // Send an unsubscribe.
         return $feedsub->unsubscribe();
     }
 }
Example #23
0
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
define('INSTALLDIR', realpath(dirname(__FILE__) . '/../../..'));
$helptext = <<<END_OF_HELP
resub-feed.php
Resubscribe to any soon expiring feeds. Default time to expiration is 1 day.

END_OF_HELP;
require_once INSTALLDIR . '/scripts/commandline.inc';
try {
    $sub = FeedSub::renewalCheck();
} catch (NoResultException $e) {
    echo 'There were no expiring feeds.';
    exit;
}
while ($sub->fetch()) {
    echo "Renewing feed subscription\n\tExp.: {$sub->sub_end}\n\tFeed: {$sub->uri}\n\tHub:  {$sub->huburi}\n";
    $sub->renew();
}
echo "Done!";
Example #24
0
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
define('INSTALLDIR', realpath(dirname(__FILE__) . '/../../..'));
$helptext = <<<END_OF_HELP
gcfeeds.php [options]
Clean up feeds that no longer have subscribers.

END_OF_HELP;
require_once INSTALLDIR . '/scripts/commandline.inc';
$feedsub = new FeedSub();
while ($feedsub->fetch()) {
    print $feedsub->uri . "(" . $feedsub->sub_state . ")";
    $result = $feedsub->garbageCollect();
    if ($result) {
        print " INACTIVE\n";
    } else {
        print " ACTIVE\n";
    }
}