<commit_before><?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Show an external user's profile information
 *
 * PHP version 5
 *
 * LICENCE: 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/>.
 *
 * @category  API
 * @package   GNUsocial
 * @author    <NAME> <<EMAIL>>
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link      http://www.gnu.org/software/social/
 */

if (!defined('GNUSOCIAL')) { exit(1); }

/**
 * Ouputs information for a user, specified by ID or screen name.
 * The user's most recent status will be returned inline.
 */
class ApiExternalUserShowAction extends ApiPrivateAuthAction
{
    /**
     * Take arguments for running
     *
     * @param array $args $_REQUEST args
     *
     * @return boolean success flag
     *
     */
    protected function prepare(array $args=array())
    {
        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 there's multiple redirects the _first_ redirect is most likely to be the real profileurl
			if(is_array($redrected_profileurl)) {
				$profileurl = $redrected_profileurl[0];
			}

			// if only one redirect
			elseif($redrected_profileurl !== false) {
				$profileurl = $redrected_profileurl;
			}
			
		}
		
		// get local profile
		$local_profile = Profile::getKV('profileurl',$profileurl);

		$this->profile = new stdClass();

		if($local_profile) {
			$this->profile->local = $this->twitterUserArray($local_profile);

			$username = $this->profile->local['screen_name'];	
			
			// if profile url is not ending with nickname, this is probably a single user instance
			if(!substr($profileurl, -strlen($username))===$username) {
				$instanceurl = $profileurl;
				}

			// multi user instance
			else {			
				$instanceurl = substr($profileurl, 0, strrpos($profileurl, '/'));				
				}			
			
			}
		
		// we don't know this user
		else {
			
			// if profile url ends with '/' this is probably an unknown single user instance
			if(substr($profileurl, -1)==='/') {
				$instanceurl = $profileurl;
				$username = 1;		
				}

			// multi user instance
			else {
				$username = substr($profileurl, strrpos($profileurl, '/')+1);			
				$instanceurl = substr($profileurl, 0, strrpos($profileurl, '/'));											
				}			
			
			}
		
		// get profile from external instance
		$apicall = $instanceurl.'/api/users/show.json?id='.$username; 	
		stream_context_set_default(array('http' => array('method' => 'GET')));
        $this->profile->external = json_decode(file_get_contents($apicall));        

        return true;
    }

    /**
     * Handle the request
     *
     * Check the format and show the user info
     *
     * @param array $args $_REQUEST data (unused)
     *
     * @return void
     */
    protected function handle()
    {
        parent::handle();

        $this->initDocument('json');
		$this->showJsonObjects($this->profile);
        $this->endDocument('json');
    }

    /**
     * Return true if read only.
     *
     * MAY override
     *
     * @param array $args other arguments
     *
     * @return boolean is read only action?
     */
    function isReadOnly($args)
    {
        return true;
    }
    

    /**
     * Get redirect(s) for an url
     *
     */
	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;
	}<commit_msg>Use GNU social HTTPClient to GET and HEAD (consistent HTTP config)<commit_after><?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Show an external user's profile information
 *
 * PHP version 5
 *
 * LICENCE: 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/>.
 *
 * @category  API
 * @package   GNUsocial
 * @author    <NAME> <<EMAIL>>
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link      http://www.gnu.org/software/social/
 */

if (!defined('GNUSOCIAL')) { exit(1); }

/**
 * Ouputs information for a user, specified by ID or screen name.
 * The user's most recent status will be returned inline.
 */
class ApiExternalUserShowAction extends ApiPrivateAuthAction
{
    /**
     * Take arguments for running
     *
     * @param array $args $_REQUEST args
     *
     * @return boolean success flag
     *
     */
    protected function prepare(array $args=array())
    {
        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);

		$this->profile = new stdClass();

		if($local_profile) {
			$this->profile->local = $this->twitterUserArray($local_profile);

			$username = $this->profile->local['screen_name'];	
			
			// if profile url is not ending with nickname, this is probably a single user instance
			if(!substr($profileurl, -strlen($username))===$username) {
				$instanceurl = $profileurl;
				}

			// multi user instance
			else {			
				$instanceurl = substr($profileurl, 0, strrpos($profileurl, '/'));				
				}			
			
			}
		
		// we don't know this user
		else {
			
			// if profile url ends with '/' this is probably an unknown single user instance
			if(substr($profileurl, -1)==='/') {
				$instanceurl = $profileurl;
				$username = 1;		
				}

			// multi user instance
			else {
				$username = substr($profileurl, strrpos($profileurl, '/')+1);			
				$instanceurl = substr($profileurl, 0, strrpos($profileurl, '/'));											
				}			
			
			}
		
		// 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;

        return true;
    }

    /**
     * Handle the request
     *
     * Check the format and show the user info
     *
     * @param array $args $_REQUEST data (unused)
     *
     * @return void
     */
    protected function handle()
    {
        parent::handle();

        $this->initDocument('json');
		$this->showJsonObjects($this->profile);
        $this->endDocument('json');
    }

    /**
     * Return true if read only.
     *
     * MAY override
     *
     * @param array $args other arguments
     *
     * @return boolean is read only action?
     */
    function isReadOnly($args)
    {
        return true;
    }
    

    /**
     * Get redirect(s) for an url
     *
     * @return mixed  Location URL if redirect, null if no Location header (through HTTP_Request2_Response getHeader())
     */
	function getRedirectUrl ($url) {
        $client = new HTTPClient();
        $response = $client->head($url);
        return $response->getHeader('Location');    // null if it isn't set
	}
{'fraction_non_alphanumeric': 0.12442817932296432, 'fraction_numerical': 0.0040027447392497716, 'mean_word_length': 2.726033233915637, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 48, 'https://': 0, 'lorem ipsum': 0, 'www.': 6, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5300916', 'n_tokens_mistral': 2852, 'n_tokens_neox': 2519, 'n_words': 790}