Example #1
0
 /**
  * get facebook profiles feed
  */
 public function actionFeed()
 {
     header('Content-Type: application/json; charset=utf-8');
     $params = ['limit' => !empty($_GET['limit']) ? (int) $_GET['limit'] : '', 'since' => !empty($_GET['since']) ? $_GET['since'] : null, 'until' => !empty($_GET['until']) ? $_GET['until'] : null, 'fields' => !empty($_GET['fields']) ? $_GET['fields'] : ''];
     try {
         $profileDiscovery = new ProfileDiscovery($_GET['profile']);
         $profile = $profileDiscovery->discovery();
         if (!$profile) {
             $data = json_encode(['error' => ['message' => "Profile '{$_GET['profile']}' not found"]]);
             Yii::app()->end(json_encode($data), true);
         }
         if (!empty($params['until']) && !empty($profile->first_post_date)) {
             if ($params['until'] >= $profile->first_post_date) {
                 Yii::app()->end(new EFacebookFeedResponse([]), true);
             }
         }
         $feedDiscovery = new FeedDiscovery($profile, $params);
         $feed = $feedDiscovery->discovery();
         if (empty($feed)) {
             $profile->updateFirstPostDate();
         }
         $response = new EFacebookFeedResponse($feed, $params);
         $response->setDefaultFields(EFacebookFields::getProfileDefaultFields($profile))->setTimeField($profile->feed_time_field);
         Yii::app()->end($response, true);
     } catch (\Exception $e) {
         $data = json_encode(['error' => ['message' => $e->getMessage()]]);
         Yii::app()->end(json_encode($data), true);
     }
 }
Example #2
0
 /**
  * Handle the request
  *
  * @param array $args $_REQUEST data (unused)
  *
  * @return void
  */
 protected function handle()
 {
     parent::handle();
     $discover = new FeedDiscovery();
     try {
         $feeduri = $discover->discoverFromURL($this->url);
         if ($feeduri) {
             $huburi = $discover->getHubLink();
         }
     } catch (FeedSubNoFeedException $e) {
         $this->clientError(_('No feed found'), 403);
     } catch (FeedSubBadResponseException $e) {
         $this->clientError(_('No hub found'), 403);
     }
     $hub_status = array();
     if ($huburi) {
         $hub_status = array('huburi' => $huburi);
     }
     $this->initDocument('json');
     $this->showJsonObjects($hub_status);
     $this->endDocument('json');
 }
Example #3
0
 /**
  * Create local ostatus_profile and profile/user_group entries for
  * the provided remote user or group.
  * This should never return null -- you will either get an object or
  * an exception will be thrown.
  *
  * @param ActivityObject $object
  * @param array $hints
  *
  * @return Ostatus_profile
  */
 protected static function createActivityObjectProfile(ActivityObject $object, array $hints = array())
 {
     $homeuri = $object->id;
     $discover = false;
     if (!$homeuri) {
         common_log(LOG_DEBUG, __METHOD__ . " empty actor profile URI: " . var_export($activity, true));
         // TRANS: Exception.
         throw new Exception(_m('No profile URI.'));
     }
     $user = User::getKV('uri', $homeuri);
     if ($user instanceof User) {
         // TRANS: Exception.
         throw new Exception(_m('Local user cannot be referenced as remote.'));
     }
     if (OStatusPlugin::localGroupFromUrl($homeuri)) {
         // TRANS: Exception.
         throw new Exception(_m('Local group cannot be referenced as remote.'));
     }
     $ptag = Profile_list::getKV('uri', $homeuri);
     if ($ptag instanceof Profile_list) {
         $local_user = User::getKV('id', $ptag->tagger);
         if ($local_user instanceof User) {
             // TRANS: Exception.
             throw new Exception(_m('Local list cannot be referenced as remote.'));
         }
     }
     if (array_key_exists('feedurl', $hints)) {
         $feeduri = $hints['feedurl'];
     } else {
         $discover = new FeedDiscovery();
         $feeduri = $discover->discoverFromURL($homeuri);
     }
     if (array_key_exists('salmon', $hints)) {
         $salmonuri = $hints['salmon'];
     } else {
         if (!$discover) {
             $discover = new FeedDiscovery();
             $discover->discoverFromFeedURL($hints['feedurl']);
         }
         // XXX: NS_REPLIES is deprecated anyway, so let's remove it in the future.
         $salmonuri = $discover->getAtomLink(Salmon::REL_SALMON) ?: $discover->getAtomLink(Salmon::NS_REPLIES);
     }
     if (array_key_exists('hub', $hints)) {
         $huburi = $hints['hub'];
     } else {
         if (!$discover) {
             $discover = new FeedDiscovery();
             $discover->discoverFromFeedURL($hints['feedurl']);
         }
         $huburi = $discover->getHubLink();
     }
     if (!$huburi && !common_config('feedsub', 'fallback_hub') && !common_config('feedsub', 'nohub')) {
         // We can only deal with folks with a PuSH hub
         throw new FeedSubNoHubException();
     }
     $oprofile = new Ostatus_profile();
     $oprofile->uri = $homeuri;
     $oprofile->feeduri = $feeduri;
     $oprofile->salmonuri = $salmonuri;
     $oprofile->created = common_sql_now();
     $oprofile->modified = common_sql_now();
     if ($object->type == ActivityObject::PERSON) {
         $profile = new Profile();
         $profile->created = common_sql_now();
         self::updateProfile($profile, $object, $hints);
         $oprofile->profile_id = $profile->insert();
         if ($oprofile->profile_id === false) {
             // TRANS: Server exception.
             throw new ServerException(_m('Cannot save local profile.'));
         }
     } else {
         if ($object->type == ActivityObject::GROUP) {
             $profile = new Profile();
             $profile->query('BEGIN');
             $group = new User_group();
             $group->uri = $homeuri;
             $group->created = common_sql_now();
             self::updateGroup($group, $object, $hints);
             // TODO: We should do this directly in User_group->insert()!
             // currently it's duplicated in User_group->update()
             // AND User_group->register()!!!
             $fields = array('nickname' => 'nickname', 'fullname' => 'fullname', 'mainpage' => 'profileurl', 'homepage' => 'homepage', 'description' => 'bio', 'location' => 'location', 'created' => 'created', 'modified' => 'modified');
             foreach ($fields as $gf => $pf) {
                 $profile->{$pf} = $group->{$gf};
             }
             $profile_id = $profile->insert();
             if ($profile_id === false) {
                 $profile->query('ROLLBACK');
                 throw new ServerException(_('Profile insertion failed.'));
             }
             $group->profile_id = $profile_id;
             $oprofile->group_id = $group->insert();
             if ($oprofile->group_id === false) {
                 $profile->query('ROLLBACK');
                 // TRANS: Server exception.
                 throw new ServerException(_m('Cannot save local profile.'));
             }
             $profile->query('COMMIT');
         } else {
             if ($object->type == ActivityObject::_LIST) {
                 $ptag = new Profile_list();
                 $ptag->uri = $homeuri;
                 $ptag->created = common_sql_now();
                 self::updatePeopletag($ptag, $object, $hints);
                 $oprofile->peopletag_id = $ptag->insert();
                 if ($oprofile->peopletag_id === false) {
                     // TRANS: Server exception.
                     throw new ServerException(_m('Cannot save local list.'));
                 }
             }
         }
     }
     $ok = $oprofile->insert();
     if ($ok === false) {
         // TRANS: Server exception.
         throw new ServerException(_m('Cannot save OStatus profile.'));
     }
     $avatar = self::getActivityObjectAvatar($object, $hints);
     if ($avatar) {
         try {
             $oprofile->updateAvatar($avatar);
         } catch (Exception $ex) {
             // Profile is saved, but Avatar is messed up. We're
             // just going to continue.
             common_log(LOG_WARNING, "Exception saving OStatus profile avatar: " . $ex->getMessage());
         }
     }
     return $oprofile;
 }
Example #4
0
 /**
  * Create local ostatus_profile and profile/user_group entries for
  * the provided remote user or group.
  * This should never return null -- you will either get an object or
  * an exception will be thrown.
  *
  * @param ActivityObject $object
  * @param array $hints
  *
  * @return Ostatus_profile
  */
 protected static function createActivityObjectProfile($object, $hints = array())
 {
     $homeuri = $object->id;
     $discover = false;
     if (!$homeuri) {
         common_log(LOG_DEBUG, __METHOD__ . " empty actor profile URI: " . var_export($activity, true));
         // TRANS: Exception.
         throw new Exception(_m('No profile URI.'));
     }
     $user = User::staticGet('uri', $homeuri);
     if ($user) {
         // TRANS: Exception.
         throw new Exception(_m('Local user cannot be referenced as remote.'));
     }
     if (OStatusPlugin::localGroupFromUrl($homeuri)) {
         // TRANS: Exception.
         throw new Exception(_m('Local group cannot be referenced as remote.'));
     }
     $ptag = Profile_list::staticGet('uri', $homeuri);
     if ($ptag) {
         $local_user = User::staticGet('id', $ptag->tagger);
         if (!empty($local_user)) {
             // TRANS: Exception.
             throw new Exception(_m('Local list cannot be referenced as remote.'));
         }
     }
     if (array_key_exists('feedurl', $hints)) {
         $feeduri = $hints['feedurl'];
     } else {
         $discover = new FeedDiscovery();
         $feeduri = $discover->discoverFromURL($homeuri);
     }
     if (array_key_exists('salmon', $hints)) {
         $salmonuri = $hints['salmon'];
     } else {
         if (!$discover) {
             $discover = new FeedDiscovery();
             $discover->discoverFromFeedURL($hints['feedurl']);
         }
         $salmonuri = $discover->getAtomLink(Salmon::NS_REPLIES);
     }
     if (array_key_exists('hub', $hints)) {
         $huburi = $hints['hub'];
     } else {
         if (!$discover) {
             $discover = new FeedDiscovery();
             $discover->discoverFromFeedURL($hints['feedurl']);
         }
         $huburi = $discover->getHubLink();
     }
     if (!$huburi && !common_config('feedsub', 'fallback_hub')) {
         // We can only deal with folks with a PuSH hub
         throw new FeedSubNoHubException();
     }
     $oprofile = new Ostatus_profile();
     $oprofile->uri = $homeuri;
     $oprofile->feeduri = $feeduri;
     $oprofile->salmonuri = $salmonuri;
     $oprofile->created = common_sql_now();
     $oprofile->modified = common_sql_now();
     if ($object->type == ActivityObject::PERSON) {
         $profile = new Profile();
         $profile->created = common_sql_now();
         self::updateProfile($profile, $object, $hints);
         $oprofile->profile_id = $profile->insert();
         if (!$oprofile->profile_id) {
             // TRANS: Server exception.
             throw new ServerException(_m('Cannot save local profile.'));
         }
     } else {
         if ($object->type == ActivityObject::GROUP) {
             $group = new User_group();
             $group->uri = $homeuri;
             $group->created = common_sql_now();
             self::updateGroup($group, $object, $hints);
             $oprofile->group_id = $group->insert();
             if (!$oprofile->group_id) {
                 // TRANS: Server exception.
                 throw new ServerException(_m('Cannot save local profile.'));
             }
         } else {
             if ($object->type == ActivityObject::_LIST) {
                 $ptag = new Profile_list();
                 $ptag->uri = $homeuri;
                 $ptag->created = common_sql_now();
                 self::updatePeopletag($ptag, $object, $hints);
                 $oprofile->peopletag_id = $ptag->insert();
                 if (!$oprofile->peopletag_id) {
                     // TRANS: Server exception.
                     throw new ServerException(_m('Cannot save local list.'));
                 }
             }
         }
     }
     $ok = $oprofile->insert();
     if (!$ok) {
         // TRANS: Server exception.
         throw new ServerException(_m('Cannot save OStatus profile.'));
     }
     $avatar = self::getActivityObjectAvatar($object, $hints);
     if ($avatar) {
         try {
             $oprofile->updateAvatar($avatar);
         } catch (Exception $ex) {
             // Profile is saved, but Avatar is messed up. We're
             // just going to continue.
             common_log(LOG_WARNING, "Exception saving OStatus profile avatar: " . $ex->getMessage());
         }
     }
     return $oprofile;
 }
 /**
  * @dataProvider provider
  *
  */
 public function testProduction($url, $html, $expected)
 {
     $sub = new FeedDiscovery();
     $url = $sub->discoverFromHTML($url, $html);
     $this->assertEquals($expected, $url);
 }
 /**
  * Look up and if necessary create an Ostatus_profile for the remote entity
  * with the given profile page URL. This should never return null -- you
  * will either get an object or an exception will be thrown.
  *
  * @param string $profile_url
  * @return Ostatus_profile
  * @throws Exception on various error conditions
  * @throws OStatusShadowException if this reference would obscure a local user/group
  */
 public static function updateProfileURL($profile_url, $hints = array())
 {
     $oprofile = null;
     $hints['profileurl'] = $profile_url;
     // Fetch the URL
     // XXX: HTTP caching
     $client = new HTTPClient();
     $client->setHeader('Accept', 'text/html,application/xhtml+xml');
     $response = $client->get($profile_url);
     if (!$response->isOk()) {
         // TRANS: Exception. %s is a profile URL.
         throw new Exception(sprintf(_('Could not reach profile page %s.'), $profile_url));
     }
     // Check if we have a non-canonical URL
     $finalUrl = $response->getUrl();
     if ($finalUrl != $profile_url) {
         $hints['profileurl'] = $finalUrl;
     }
     // Try to get some hCard data
     $body = $response->getBody();
     $hcardHints = DiscoveryHints::hcardHints($body, $finalUrl);
     if (!empty($hcardHints)) {
         $hints = array_merge($hints, $hcardHints);
     }
     // Check if they've got an LRDD header
     $lrdd = LinkHeader::getLink($response, 'lrdd', 'application/xrd+xml');
     if (!empty($lrdd)) {
         $xrd = Discovery::fetchXrd($lrdd);
         $xrdHints = DiscoveryHints::fromXRD($xrd);
         $hints = array_merge($hints, $xrdHints);
     }
     // If discovery found a feedurl (probably from LRDD), use it.
     if (array_key_exists('feedurl', $hints)) {
         return self::ensureFeedURL($hints['feedurl'], $hints);
     }
     // Get the feed URL from HTML
     $discover = new FeedDiscovery();
     $feedurl = $discover->discoverFromHTML($finalUrl, $body);
     if (!empty($feedurl)) {
         $hints['feedurl'] = $feedurl;
         return self::ensureFeedURL($feedurl, $hints);
     }
     // TRANS: Exception. %s is a URL.
     throw new Exception(sprintf(_m('Could not find a feed URL for profile page %s.'), $finalUrl));
 }
if (empty($args[0]) || !Validate::uri($args[0])) {
    print "{$helptext}";
    exit(1);
}
$uri = $args[0];
$oprofile = Ostatus_profile::staticGet('uri', $uri);
if (!$oprofile) {
    print "No OStatus remote profile known for URI {$uri}\n";
    exit(1);
}
print "Old profile state for {$oprofile->uri}\n";
showProfile($oprofile);
print "\n";
print "Re-running feed discovery for profile URL {$oprofile->uri}\n";
// @fixme will bork where the URI isn't the profile URL for now
$discover = new FeedDiscovery();
$feedurl = $discover->discoverFromURL($oprofile->uri);
$huburi = $discover->getHubLink();
$salmonuri = $discover->getAtomLink(Salmon::NS_REPLIES);
print "  Feed URL: {$feedurl}\n";
print "  Hub URL: {$huburi}\n";
print "  Salmon URL: {$salmonuri}\n";
if ($feedurl != $oprofile->feeduri || $salmonuri != $oprofile->salmonuri) {
    print "\n";
    print "Updating...\n";
    // @fixme update keys :P
    #$orig = clone($oprofile);
    #$oprofile->feeduri = $feedurl;
    #$oprofile->salmonuri = $salmonuri;
    #$ok = $oprofile->update($orig);
    $ok = $oprofile->query('UPDATE ostatus_profile SET ' . 'feeduri=\'' . $oprofile->escape($feedurl) . '\',' . 'salmonuri=\'' . $oprofile->escape($salmonuri) . '\' ' . 'WHERE uri=\'' . $oprofile->escape($uri) . '\'');
    exit(1);
}
$uri = $args[0];
$oprofile = Ostatus_profile::getKV('uri', $uri);
if (!$oprofile) {
    print "No OStatus remote profile known for URI {$uri}\n";
    exit(1);
}
print "Old profile state for {$oprofile->uri}\n";
showProfile($oprofile);
print "\n";
print "Re-running feed discovery for profile URL {$oprofile->uri}\n";
$feedurl = null;
$salmonuri = null;
// @fixme will bork where the URI isn't the profile URL for now
$discover = new FeedDiscovery();
try {
    $feedurl = $discover->discoverFromURL($oprofile->uri);
    $salmonuri = $discover->getAtomLink(Salmon::REL_SALMON) ?: $discover->getAtomLink(Salmon::NS_REPLIES);
    // NS_REPLIES is deprecated
    if (empty($salmonuri)) {
        throw new FeedSubNoSalmonException('No salmon upstream URI was found');
    }
} catch (FeedSubException $e) {
    $acct = $oprofile->localProfile()->getAcctUri();
    print "Could not discover feeds HTML response, trying reconstructed acct URI: {$acct}\n";
    $disco = new Discovery();
    $xrd = $disco->lookup($acct);
    $hints = DiscoveryHints::fromXRD($xrd);
    if (empty($feedurl) && !array_key_exists('feedurl', $hints)) {
        throw new FeedSubNoFeedException($acct);
Example #9
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;
 }