faster retrieval of external profiles

This commit is contained in:
Hannes Mannerheim 2015-06-02 13:53:36 +02:00
parent 4677503011
commit d5a3c0f003
4 changed files with 92 additions and 61 deletions

View File

@ -47,64 +47,98 @@ class ApiExternalUserShowAction extends ApiPrivateAuthAction
parent::prepare($args);
$profileurl = urldecode($this->arg('profileurl'));
// if this is an instance/user/1234 type url, try to find real profile url
if(strstr($profileurl, '/user/')) {
$redrected_profileurl = $this->getRedirectUrl($profileurl);
if (!empty($redrected_profileurl)) {
$profileurl = $redrected_profileurl;
}
}
// get local profile
$local_profile = Profile::getKV('profileurl',$profileurl);
$nickname = urldecode($this->arg('nickname'));
$this->profile = new stdClass();
$this->profile->external = null;
$this->profile->local = null;
// we can get urls of two types of urls (1) ://instance/nickname
// (2) ://instance/user/1234
//
// in case (1) we have the problem that the html can be outdated,
// i.e. the user can have changed her nickname. we also have no idea
// if it is a multi or single user instance, which forces us to
// guess the api root url.
//
// in case (2) we have another problem: we can't use that url to find
// the local profile for the external user, we need url:s of type (2)
// for that. so we have to try getting the nickname from the external
// instance first
// case (2)
if(strstr($profileurl, '/user/')) {
$external_user_id = substr($profileurl,strpos($profileurl,'/user/')+6);
$external_instance_url = substr($profileurl,0,strpos($profileurl,'/user/')+1);
if(!is_numeric($external_user_id)) {
return true;
}
$external_profile = $this->getProfileFromExternalInstance($external_instance_url,$external_user_id);
if(!isset($external_profile->statusnet_profile_url)) {
return true;
}
$this->profile->external = $external_profile;
$local_profile = Profile::getKV('profileurl',$external_profile->statusnet_profile_url);
if(!$local_profile instanceof Profile) {
return true;
}
if($local_profile) {
$this->profile->local = $this->twitterUserArray($local_profile);
return true;
}
$username = $this->profile->local['screen_name'];
// case (1)
$local_profile = Profile::getKV('profileurl',$profileurl);
if($local_profile instanceof Profile) {
// if profile url is not ending with nickname, this is probably a single user instance
if(!substr($profileurl, -strlen($username))===$username) {
$instanceurl = $profileurl;
if(!substr($local_profile->profileurl, -strlen($local_profile->nickname))===$local_profile->nickname) {
$external_instance_url = $local_profile->profileurl;
}
// multi user instance
else {
$instanceurl = substr($profileurl, 0, strrpos($profileurl, '/'));
$external_instance_url = substr($local_profile->profileurl, 0, strrpos($local_profile->profileurl, '/'));
}
$external_profile = $this->getProfileFromExternalInstance($external_instance_url,$local_profile->nickname);
if(!isset($external_profile->statusnet_profile_url)) {
return true;
}
// we don't know this user
else {
$this->profile->external = $external_profile;
$this->profile->local = $this->twitterUserArray($local_profile);
return true;
}
// if we don't know about this user, or the user has changed nickname
// if profile url ends with '/' this is probably an unknown single user instance
if(substr($profileurl, -1)==='/') {
$instanceurl = $profileurl;
$username = 1;
$user_id_or_nickname = 1;
}
// multi user instance
else {
$username = substr($profileurl, strrpos($profileurl, '/')+1);
$user_id_or_nickname = substr($profileurl, strrpos($profileurl, '/')+1);
$instanceurl = substr($profileurl, 0, strrpos($profileurl, '/'));
}
$external_profile = $this->getProfileFromExternalInstance($instanceurl,$user_id_or_nickname);
if(!isset($external_profile->statusnet_profile_url)) {
return true;
}
// get profile from external instance
$apicall = $instanceurl.'/api/users/show.json?id='.$username;
$client = new HTTPClient();
$response = $client->get($apicall);
// json_decode returns null if it fails to decode
$this->profile->external = $response->isOk() ? json_decode($response->getBody()) : null;
$this->profile->external = $external_profile;
return true;
}
/**
@ -141,20 +175,17 @@ class ApiExternalUserShowAction extends ApiPrivateAuthAction
/**
* Get redirect(s) for an url
* Get profile from external instance
*
* @return null or profile object
*/
function getRedirectUrl ($url) {
stream_context_set_default(array(
'http' => array(
'method' => 'HEAD'
)
));
$headers = get_headers($url, 1);
if ($headers !== false && isset($headers['Location'])) {
return $headers['Location'];
}
return false;
function getProfileFromExternalInstance($instance_url,$user_id_or_nickname)
{
$apicall = $instance_url.'/api/users/show.json?id='.$user_id_or_nickname;
$client = new HTTPClient();
$response = $client->get($apicall);
// json_decode returns null if it fails to decode
return $response->isOk() ? json_decode($response->getBody()) : null;
}

View File

@ -518,10 +518,10 @@ class QvitterAction extends ApiAction
<script type="text/javascript" src="<?php print $qvitterpath; ?>js/lib/jquery.jWindowCrop.js?changed=<?php print date('YmdHis',filemtime(QVITTERDIR.'/js/lib/jquery.jWindowCrop.js')); ?>"></script>
<script type="text/javascript" src="<?php print $qvitterpath; ?>js/lib/load-image.min.js?changed=<?php print date('YmdHis',filemtime(QVITTERDIR.'/js/lib/load-image.min.js')); ?>"></script>
<script type="text/javascript" src="<?php print $qvitterpath; ?>js/lib/xregexp-all-min-2.0.0.js?changed=<?php print date('YmdHis',filemtime(QVITTERDIR.'/js/lib/xregexp-all-min-2.0.0.js')); ?>"></script>
<script type="text/javascript" src="<?php print $qvitterpath; ?>js/dom-functions.js?changed=<?php print date('YmdHis',filemtime(QVITTERDIR.'/js/dom-functions.js')); ?>"></script>
<script type="text/javascript" src="<?php print $qvitterpath; ?>js/misc-functions.js?changed=<?php print date('YmdHis',filemtime(QVITTERDIR.'/js/misc-functions.js')); ?>"></script>
<script type="text/javascript" src="<?php print $qvitterpath; ?>js/ajax-functions.js?changed=<?php print date('YmdHis',filemtime(QVITTERDIR.'/js/ajax-functions.js')); ?>"></script>
<script type="text/javascript" src="<?php print $qvitterpath; ?>js/qvitter.js?changed=<?php print date('YmdHis',filemtime(QVITTERDIR.'/js/qvitter.js')); ?>"></script>
<script charset="utf-8" type="text/javascript" src="<?php print $qvitterpath; ?>js/dom-functions.js?changed=<?php print date('YmdHis',filemtime(QVITTERDIR.'/js/dom-functions.js')); ?>"></script>
<script charset="utf-8" type="text/javascript" src="<?php print $qvitterpath; ?>js/misc-functions.js?changed=<?php print date('YmdHis',filemtime(QVITTERDIR.'/js/misc-functions.js')); ?>"></script>
<script charset="utf-8" type="text/javascript" src="<?php print $qvitterpath; ?>js/ajax-functions.js?changed=<?php print date('YmdHis',filemtime(QVITTERDIR.'/js/ajax-functions.js')); ?>"></script>
<script charset="utf-8" type="text/javascript" src="<?php print $qvitterpath; ?>js/qvitter.js?changed=<?php print date('YmdHis',filemtime(QVITTERDIR.'/js/qvitter.js')); ?>"></script>
<?php
// event for other plugins to add scripts to qvitter

View File

@ -1041,7 +1041,7 @@ $('body').on('click','a', function(e) {
// local profile id and follow class
var followLocalIdHtml = '';
var followingClass = '';
if(typeof data.local != 'undefined') {
if(typeof data.local != 'undefined' && data.local !== null) {
followLocalIdHtml = ' data-follow-user-id="' + data.local.id + '"';
if(data.local.following) {