/** * 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); } }
/** * 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'); }
/** * 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; }
/** * 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);
/** * @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; }