Browse Source

Init commit (files)

Joachim M. Giæver 6 years ago
parent
commit
84770c6e70
8 changed files with 412 additions and 1 deletions
  1. 23 1
      README.md
  2. 24 0
      client/gogsapi.php
  3. 78 0
      client/request/repos.php
  4. 43 0
      client/request/requestbase.php
  5. 11 0
      client/request/requestinterface.php
  6. 24 0
      client/request/user.php
  7. 37 0
      index.php
  8. 172 0
      lib/curl.php

+ 23 - 1
README.md

@@ -1,3 +1,25 @@
 # gogs-php-api-client
 
-A client to query Gogs (https://gogs.io) API from PHP.
+A client to query Gogs (https://gogs.io) API from PHP.
+
+## Uages: 
+
+A guide on how to use will come shortly!
+
+### Quick example:
+
+Clone the repo. Set the `API_URL` and `API_TOKEN` in the index-file. 
+
+```php
+
+$client =  new \Client\GogsAPI(API_URL, API_TOKEN);
+
+$me = $client->user();
+$other = $client->user("username");
+
+$repos = $me->get("/repos")->load();
+
+// Loop through every repo
+for($repo = $repos->current(); $repo != false; $repo = $repos->next())
+    var_dump($repo);
+

+ 24 - 0
client/gogsapi.php

@@ -0,0 +1,24 @@
+<?php namespace Client;
+
+class GogsAPI {
+    use \Lib\Curl;
+
+    public function __construct($api_url, $api_token) {
+        $this->url = $api_url;
+        $this->token = $api_token;
+        $this->authorized("/user");
+    }
+
+    public function user($name = "") {
+        $scope = sprintf("%s/user", $this->url);
+
+        if ($name != "") {
+            $scope = sprintf("%ss/%s", $scope, $name);
+        }
+
+        return new Request\User($scope, $this->token);
+    }
+
+    public function __destruct() {}
+}
+?>

+ 78 - 0
client/request/repos.php

@@ -0,0 +1,78 @@
+<?php 
+
+namespace Client\Request {
+    class Repos extends RequestBase {
+        private $repo = array();
+
+        protected function json_set_property($objs) {
+            foreach ($objs as $key => $obj) {
+                $this->repo[$key] = new Repos\Repo(
+                    sprintf("/repos/%s/%s", 
+                        $obj->owner->username, 
+                        $obj->name
+                    ),
+                    $this->token
+                );
+                $this->repo[$key]->json_set_property($obj);
+            }
+        }
+
+        public function current() {
+            return current($this->repo);
+        }
+
+        public function next() {
+            return next($this->repo);
+        }
+
+        public function reset() {
+            return reset($this->repo);
+        }
+
+        public function __destruct() {}
+    }
+}
+
+namespace Client\Request\Repos {
+    class Repo extends \Client\Request\RequestBase { 
+        public $rid;
+        public $rowner;
+        public $rname;
+        public $rfull_name;
+        public $rdescription;
+        public $rprivate;
+        public $rfork;
+        public $rparent;
+        public $rempty;
+        public $rmirror;
+        public $rsize;
+        public $rhtml_url;
+        public $rssh_url;
+        public $rclone_url;
+        public $rwebsite;
+        public $rstars_count;
+        public $rforks_count;
+        public $rwathcers_count;
+        public $ropen_issues_count;
+        public $rpublic_branch;
+        public $rcreated_at;
+        public $rupdated_at;
+        public $rpermissions;
+
+        public function __construct($api_url, $token) {
+            if (!strpos($api_url, API_URL))
+                $api_url = sprintf("%s/%s", API_URL, $api_url);
+            parent::__construct($api_url, $token);
+        }
+        
+        protected function json_set_property($obj) {
+            foreach($obj as $key => $value) {
+                $key = 'r' . $key;
+                if (property_exists($this, $key))
+                    $this->{$key} = $value;
+            }
+        }
+
+        public function __destruct() {}
+    }
+}

+ 43 - 0
client/request/requestbase.php

@@ -0,0 +1,43 @@
+<?php namespace Client\Request;
+
+abstract class RequestBase implements RequestInterface {
+
+    protected $loaded = false;
+
+    use \Lib\Curl {
+        get as protected mget;
+    }
+
+    public function __construct($api_url, $api_token) {
+        $this->url = $api_url;
+        $this->token = $api_token;
+    }
+
+    public function load() {
+        $jenc =  $this->mget("", "");
+        $this->json_set_property($this->json_decode($jenc));
+        return $this;
+    }
+
+    public function get($scope) {
+        $s = substr($scope, strrpos($scope, "/") + 1);
+        echo sprintf("Scope: %s\b", $s);
+        switch ($s) {
+        case "repos":
+            return new Repos($this->url . $scope, $this->token);
+        }
+    }
+
+    private function json_decode($jenc) {
+        $obj = json_decode($jenc);
+
+        if (($err = json_last_error()) != JSON_ERROR_NONE)
+            throw new RequestErrorException(json_last_error_msg(), $err);
+
+        return $obj;
+    }
+
+    abstract protected function json_set_property($obj);
+}
+
+?>

+ 11 - 0
client/request/requestinterface.php

@@ -0,0 +1,11 @@
+<?php namespace Client\Request;
+
+class RequestErrorException extends \Exception {};
+
+interface RequestInterface {
+    public function __construct($api_url, $api_token);
+    public function get($scope);
+    public function __destruct();
+}
+
+?>

+ 24 - 0
client/request/user.php

@@ -0,0 +1,24 @@
+<?php namespace Client\Request;
+
+class User extends RequestBase {
+
+    public $uid;
+    public $ulogin;
+    public $ufull_name;
+    public $uemail;
+    public $uavatar_url;
+    public $uusername;
+
+    public function __destruct() {}
+
+    protected function json_set_property($obj) {
+        foreach ($obj as $key => $value) {
+            echo sprintf("KEY: %s\n", $key);
+            $key = 'u' . $key;
+            if (property_exists($this, $key))
+                $this->{$key} = $value;
+        }
+    }
+}
+
+?>

+ 37 - 0
index.php

@@ -0,0 +1,37 @@
+<?php
+
+/*
+ * TODO:
+ *
+ * Rewrite this. Shouldnt be a test file, like its now.
+ *
+ * */
+
+define('BASE_PATH', realpath(dirname(__FILE__)));
+
+
+function my_autoloader($class)
+{
+
+    $file = str_replace("\\", DIRECTORY_SEPARATOR, strtolower($class)) . ".php";
+    echo $class . ' -> ' . $file . "\n";
+    require_once BASE_PATH . DIRECTORY_SEPARATOR . $file;
+}
+spl_autoload_register('my_autoloader');
+
+try {
+    $client =  new \Client\GogsAPI(API_URL, API_TOKEN);
+
+    $me = $client->user();
+    $other = $client->user("bje007");
+
+    $repos = $me->get("/repos")->load();
+
+    for($repo = $repos->current(); $repo != false; $repo = $repos->next())
+        var_dump($repo);
+
+
+} catch (\Lib\NotAutorizedException $e) {
+    die($e->getMessage());
+}
+?>

+ 172 - 0
lib/curl.php

@@ -0,0 +1,172 @@
+<?php namespace Lib;
+
+class HTTPUnexpectedResponse extends \Exception {
+    static $ecode = array(
+        100 => 'Continue',
+        101 => 'Switching Protocols',
+        102 => 'Processing', // WebDAV; RFC 2518
+        200 => 'OK',
+        201 => 'Created',
+        202 => 'Accepted',
+        203 => 'Non-Authoritative Information', // since HTTP/1.1
+        204 => 'No Content',
+        205 => 'Reset Content',
+        206 => 'Partial Content',
+        207 => 'Multi-Status', // WebDAV; RFC 4918
+        208 => 'Already Reported', // WebDAV; RFC 5842
+        226 => 'IM Used', // RFC 3229
+        300 => 'Multiple Choices',
+        301 => 'Moved Permanently',
+        302 => 'Found',
+        303 => 'See Other', // since HTTP/1.1
+        304 => 'Not Modified',
+        305 => 'Use Proxy', // since HTTP/1.1
+        306 => 'Switch Proxy',
+        307 => 'Temporary Redirect', // since HTTP/1.1
+        308 => 'Permanent Redirect', // approved as experimental RFC
+        400 => 'Bad Request',
+        401 => 'Unauthorized',
+        402 => 'Payment Required',
+        403 => 'Forbidden',
+        404 => 'Not Found',
+        405 => 'Method Not Allowed',
+        406 => 'Not Acceptable',
+        407 => 'Proxy Authentication Required',
+        408 => 'Request Timeout',
+        409 => 'Conflict',
+        410 => 'Gone',
+        411 => 'Length Required',
+        412 => 'Precondition Failed',
+        413 => 'Request Entity Too Large',
+        414 => 'Request-URI Too Long',
+        415 => 'Unsupported Media Type',
+        416 => 'Requested Range Not Satisfiable',
+        417 => 'Expectation Failed',
+        418 => 'I\'m a teapot', // RFC 2324
+        419 => 'Authentication Timeout', // not in RFC 2616
+        420 => 'Enhance Your Calm', // Twitter
+        420 => 'Method Failure', // Spring Framework
+        422 => 'Unprocessable Entity', // WebDAV; RFC 4918
+        423 => 'Locked', // WebDAV; RFC 4918
+        424 => 'Failed Dependency', // WebDAV; RFC 4918
+        424 => 'Method Failure', // WebDAV)
+        425 => 'Unordered Collection', // Internet draft
+        426 => 'Upgrade Required', // RFC 2817
+        428 => 'Precondition Required', // RFC 6585
+        429 => 'Too Many Requests', // RFC 6585
+        431 => 'Request Header Fields Too Large', // RFC 6585
+        444 => 'No Response', // Nginx
+        449 => 'Retry With', // Microsoft
+        450 => 'Blocked by Windows Parental Controls', // Microsoft
+        451 => 'Redirect', // Microsoft
+        451 => 'Unavailable For Legal Reasons', // Internet draft
+        494 => 'Request Header Too Large', // Nginx
+        495 => 'Cert Error', // Nginx
+        496 => 'No Cert', // Nginx
+        497 => 'HTTP to HTTPS', // Nginx
+        499 => 'Client Closed Request', // Nginx
+        500 => 'Internal Server Error',
+        501 => 'Not Implemented',
+        502 => 'Bad Gateway',
+        503 => 'Service Unavailable',
+        504 => 'Gateway Timeout',
+        505 => 'HTTP Version Not Supported',
+        506 => 'Variant Also Negotiates', // RFC 2295
+        507 => 'Insufficient Storage', // WebDAV; RFC 4918
+        508 => 'Loop Detected', // WebDAV; RFC 5842
+        509 => 'Bandwidth Limit Exceeded', // Apache bw/limited extension
+        510 => 'Not Extended', // RFC 2774
+        511 => 'Network Authentication Required', // RFC 6585
+        598 => 'Network read timeout error', // Unknown
+        599 => 'Network connect timeout error', // Unknown
+    );
+}
+
+class NotAutorizedException extends \Exception{}
+
+trait Curl {
+    protected $url;
+    protected $token;
+
+    protected $user_agent = "Gogs PHP Api Client/0.0 (compatible; LINUX)";
+    protected $timeout = 30;
+    protected $max_redirects = 4;
+
+    protected function method(&$req, $scope, $params, $post, $ret) {
+        echo sprintf(
+            "URL: %s{%s} Token: %s\n", 
+            $this->url, 
+            $scope,
+            $this->token
+        );
+
+        $c = curl_init();
+
+        if (!$c) {
+            return false;
+        }
+
+        if ($post) {
+            curl_setopt($c, CURLOPT_POST, 1);
+            curl_setopt($c, CURLOPT_POSTFIELDS, $params);
+        }
+
+        curl_setopt($c, CURLOPT_USERAGENT, $this->user_agent);
+        curl_setopt($c, CURLOPT_URL, sprintf("%s%s", $this->url, $scope));
+        curl_setopt($c, CURLOPT_HTTPHEADER, array(
+            sprintf("Authorization: token %s", $this->token)
+        ));
+        curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
+        curl_setopt($c, CURLOPT_TIMEOUT, $this->timeout);
+        curl_setopt($c, CURLOPT_MAXREDIRS, $this->max_redirects);
+        curl_setopt($c, CURLOPT_FOLLOWLOCATION, true);
+
+        $req = curl_exec($c);
+
+        $status_code = curl_getinfo($c, CURLINFO_HTTP_CODE);
+
+        curl_close($c);
+
+        return $status_code;
+    }
+
+    protected function authorized($scope) {
+        if ($this->test($scope, 401)) {
+            throw new NotAutorizedException("Not authorized", 401);
+        }
+        return true;
+    }
+
+    protected function test($scope, $code = 200) {
+        $req = "";
+        return $this->method($ret, $scope, array(), false, false) == $code;
+    }
+
+    private function post($scope, $params) {
+        $req = "";
+
+        $code = $this->method($req, $scope, $params, true, true);
+
+        switch ($code) {
+        case 200:
+            return $req;
+        default:
+            throw new HTTPUnexpectedResponse(HTTPUnexpectedResponse::$ecode[$code], $code);
+        }
+    }
+
+    private function get($scope, $params) {
+        $req = "";
+
+        $code = $this->method($req, $scope, $params, false, true);
+
+        switch ($code) {
+        case 200:
+            return $req;
+        default:
+            throw new HTTPUnexpectedResponse(HTTPUnexpectedResponse::$ecode[$code], $code);
+
+        }
+    }
+
+}