<commit_before><?php namespace Todaymade\Daux\Format\Confluence;

use GuzzleHttp\Client;
use GuzzleHttp\Exception\BadResponseException;
use GuzzleHttp\Exception\ParseException;

class Api
{
    protected $base_url;
    protected $user;
    protected $pass;

    protected $space;

    public function __construct($base_url, $user, $pass)
    {
        $this->base_url = $base_url;
        $this->user = $user;
        $this->pass = $pass;
    }

    public function setSpace($space_id)
    {
        $this->space = $space_id;
    }

    protected function getClient()
    {
        $options = [
            'base_url' => $this->base_url . 'rest/api/',
            'defaults' => [
                'auth' => [$this->user, $this->pass]
            ]
        ];

        return new Client($options);
    }

    /**
     * The standard error message from guzzle is quite poor in informations,
     * this will give little bit more sense to it and return it
     *
     * @param BadResponseException $e
     * @return BadResponseException
     */
    protected function handleError(BadResponseException $e)
    {
        $request = $e->getRequest();
        $response = $e->getResponse();

        $level = floor($response->getStatusCode() / 100);

        if ($level == '4') {
            $label = 'Client error response';
        } elseif ($level == '5') {
            $label = 'Server error response';
        } else {
            $label = 'Unsuccessful response';
        }

        $message = $label .
            ' [url] ' . $request->getUrl() .
            ' [status code] ' . $response->getStatusCode() .
            ' [message] ';

        try {
            $message .= $response->json()['message'];
        } catch (ParseException $e) {
            $message .= (string) $response->getBody();
        }

        return new BadResponseException($message, $request, $response, $e->getPrevious());
    }

    /**
     * Get a list of pages
     *
     * @param integer $rootPage
     * @param bool $recursive
     * @return array
     */
    public function getList($rootPage, $recursive = false)
    {
        $increment = 15;

        // We set a limit of 15 as it appears that
        // Confluence fails silently when retrieving
        // more than 20 entries with "body.storage"
        $base_url = $url = "content/$rootPage/child/page?expand=version,body.storage&limit=$increment";
        $start = 0;

        $pages = [];

        do {
            try {
                $hierarchy = $this->getClient()->get($url)->json();
            } catch (BadResponseException $e) {
                throw $this->handleError($e);
            }

            foreach ($hierarchy['results'] as $result) {
                $pages[$result['title']] = [
                    "id" => $result['id'],
                    "title" => $result['title'],
                    "version" => $result['version']['number'],
                    "content" => $result['body']['storage']['value'],
                ];

                if ($recursive) {
                    $pages[$result['title']]['children'] = $this->getList($result['id'], true);
                }
            }

            // We don't use _links->next as after ~30 elements
            // it doesn't show any new elements. This seems
            // to be a bug in Confluence
            $start += $increment;
            $url = "$base_url&start=$start";

        } while (!empty($hierarchy['results']));

        return $pages;
    }

    /**
     * @param integer $parent_id
     * @param string $title
     * @param string $content
     * @return integer
     */
    public function createPage($parent_id, $title, $content)
    {
        $body = [
            'type' => 'page',
            'space' => ['key' => $this->space],
            'ancestors' => [['type' => 'page', 'id' => $parent_id]],
            'title' => $title,
            'body' => ['storage' => ['value' => $content, 'representation' => 'storage']]
        ];

        try {
            $response = $this->getClient()->post('content', ['json' => $body])->json();
        } catch (BadResponseException $e) {
            throw $this->handleError($e);
        }

        return $response['id'];
    }

    /**
     * @param integer $parent_id
     * @param integer $page_id
     * @param integer $newVersion
     * @param string $title
     * @param string $content
     */
    public function updatePage($parent_id, $page_id, $newVersion, $title, $content)
    {
        $body = [
            'type' => 'page',
            'space' => ['key' => $this->space],
            'ancestors' => [['type' => 'page', 'id' => $parent_id]],
            'version' => ['number' => $newVersion, "minorEdit" => false],
            'title' => $title,
            'body' => ['storage' => ['value' => $content, 'representation' => 'storage']]
        ];

        try {
            $this->getClient()->put("content/$page_id", ['json' => $body])->json();
        } catch (BadResponseException $e) {
            throw $this->handleError($e);
        }
    }

    /**
     * Delete a page
     *
     * @param integer $page_id
     * @return mixed
     */
    public function deletePage($page_id)
    {
        try {
            return $this->getClient()->delete('content/' . $page_id)->json();
        } catch (BadResponseException $e) {
            throw $this->handleError($e);
        }
    }

    /**<commit_msg>Do not send notification emails ...<commit_after><?php namespace Todaymade\Daux\Format\Confluence;

use GuzzleHttp\Client;
use GuzzleHttp\Exception\BadResponseException;
use GuzzleHttp\Exception\ParseException;

class Api
{
    protected $base_url;
    protected $user;
    protected $pass;

    protected $space;

    public function __construct($base_url, $user, $pass)
    {
        $this->base_url = $base_url;
        $this->user = $user;
        $this->pass = $pass;
    }

    public function setSpace($space_id)
    {
        $this->space = $space_id;
    }

    protected function getClient()
    {
        $options = [
            'base_url' => $this->base_url . 'rest/api/',
            'defaults' => [
                'auth' => [$this->user, $this->pass]
            ]
        ];

        return new Client($options);
    }

    /**
     * The standard error message from guzzle is quite poor in informations,
     * this will give little bit more sense to it and return it
     *
     * @param BadResponseException $e
     * @return BadResponseException
     */
    protected function handleError(BadResponseException $e)
    {
        $request = $e->getRequest();
        $response = $e->getResponse();

        $level = floor($response->getStatusCode() / 100);

        if ($level == '4') {
            $label = 'Client error response';
        } elseif ($level == '5') {
            $label = 'Server error response';
        } else {
            $label = 'Unsuccessful response';
        }

        $message = $label .
            ' [url] ' . $request->getUrl() .
            ' [status code] ' . $response->getStatusCode() .
            ' [message] ';

        try {
            $message .= $response->json()['message'];
        } catch (ParseException $e) {
            $message .= (string) $response->getBody();
        }

        return new BadResponseException($message, $request, $response, $e->getPrevious());
    }

    /**
     * Get a list of pages
     *
     * @param integer $rootPage
     * @param bool $recursive
     * @return array
     */
    public function getList($rootPage, $recursive = false)
    {
        $increment = 15;

        // We set a limit of 15 as it appears that
        // Confluence fails silently when retrieving
        // more than 20 entries with "body.storage"
        $base_url = $url = "content/$rootPage/child/page?expand=version,body.storage&limit=$increment";
        $start = 0;

        $pages = [];

        do {
            try {
                $hierarchy = $this->getClient()->get($url)->json();
            } catch (BadResponseException $e) {
                throw $this->handleError($e);
            }

            foreach ($hierarchy['results'] as $result) {
                $pages[$result['title']] = [
                    "id" => $result['id'],
                    "title" => $result['title'],
                    "version" => $result['version']['number'],
                    "content" => $result['body']['storage']['value'],
                ];

                if ($recursive) {
                    $pages[$result['title']]['children'] = $this->getList($result['id'], true);
                }
            }

            // We don't use _links->next as after ~30 elements
            // it doesn't show any new elements. This seems
            // to be a bug in Confluence
            $start += $increment;
            $url = "$base_url&start=$start";

        } while (!empty($hierarchy['results']));

        return $pages;
    }

    /**
     * @param integer $parent_id
     * @param string $title
     * @param string $content
     * @return integer
     */
    public function createPage($parent_id, $title, $content)
    {
        $body = [
            'type' => 'page',
            'space' => ['key' => $this->space],
            'ancestors' => [['type' => 'page', 'id' => $parent_id]],
            'title' => $title,
            'body' => ['storage' => ['value' => $content, 'representation' => 'storage']]
        ];

        try {
            $response = $this->getClient()->post('content', ['json' => $body])->json();
        } catch (BadResponseException $e) {
            throw $this->handleError($e);
        }

        return $response['id'];
    }

    /**
     * @param integer $parent_id
     * @param integer $page_id
     * @param integer $newVersion
     * @param string $title
     * @param string $content
     */
    public function updatePage($parent_id, $page_id, $newVersion, $title, $content)
    {
        $body = [
            'type' => 'page',
            'space' => ['key' => $this->space],
            'ancestors' => [['type' => 'page', 'id' => $parent_id]],
            'version' => ['number' => $newVersion, "minorEdit" => true],
            'title' => $title,
            'body' => ['storage' => ['value' => $content, 'representation' => 'storage']]
        ];

        try {
            $this->getClient()->put("content/$page_id", ['json' => $body])->json();
        } catch (BadResponseException $e) {
            throw $this->handleError($e);
        }
    }

    /**
     * Delete a page
     *
     * @param integer $page_id
     * @return mixed
     */
    public function deletePage($page_id)
    {
        try {
            return $this->getClient()->delete('content/' . $page_id)->json();
        } catch (BadResponseException $e) {
            throw $this->handleError($e);
        }
    }

    /**
{'fraction_non_alphanumeric': 0.16129032258064516, 'fraction_numerical': 0.002588039560033275, 'mean_word_length': 1.7893787058520236, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 141, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '1440062', 'n_tokens_mistral': 3164, 'n_tokens_neox': 3049, 'n_words': 715}