import curl
import json::static
+import json
# Specific Curl that know hot to talk to the github API
class GithubCurl
- super Curl
# Headers to use on all requests
var header: HeaderMap is noinit
# OAuth token
+ #
+ # Use an empty string to disable authentication and connect
+ # anonymously (thus less capabilities and more rate limits)
var auth: String
# User agent (is used by github to contact devs in case of problems)
init do
header = new HeaderMap
- header["Authorization"] = "token {auth}"
+ if auth != "" then header["Authorization"] = "token {auth}"
end
# Get the requested URI, and check the HTTP response. Then convert to JSON
# and check for Github errors.
- fun get_and_check(uri: String): nullable Jsonable
+ fun get_and_check(uri: String): nullable Serializable
do
- var request = new CurlHTTPRequest(uri, self)
+ var request = new CurlHTTPRequest(uri)
request.user_agent = user_agent
request.headers = header
var response = request.execute
if response isa CurlResponseSuccess then
var obj = response.body_str.parse_json
if obj isa JsonObject then
- if obj.keys.has("message") then
+ if obj.keys.has("message") and obj.keys.has("documentation_url") then
print "Message from Github API: {obj["message"] or else ""}"
print "Requested URI: {uri}"
abort
abort
else abort
end
+
+ # Get the requested URI, and check the HTTP response.
+ # Then convert to JSON and check for Github errors.
+ # Unlike `get_and_check`, error do not trigger an abort but
+ # are reported as `GithubError`.
+ fun get_and_parse(uri: String): nullable Serializable
+ do
+ var request = new CurlHTTPRequest(uri)
+ request.user_agent = user_agent
+ request.headers = header
+ var response = request.execute
+ if response isa CurlResponseSuccess then
+ var obj = response.body_str.parse_json
+ if obj isa JsonObject then
+ if obj.keys.has("message") and obj.keys.has("documentation_url") then
+ var title = "GithubAPIError"
+ var msg = obj["message"].as(not null).to_s
+ var err = new GithubError(msg, title)
+ err.json["requested_uri"] = uri
+ err.json["status_code"] = response.status_code
+ return err
+ end
+ end
+ return obj
+
+ else if response isa CurlResponseFailed then
+ var title = "CurlResponseFailed"
+ var msg = "Request to Github API failed"
+ var err = new GithubError(msg, title)
+ err.json["requested_uri"] = uri
+ err.json["error_code"] = response.error_code
+ err.json["response"] = response.error_msg
+ return err
+ else abort
+ end
+
end
+# An error thrown by the Github API.
+#
+# Depending on the kind of error, additionnal informations can be stored in
+# the error object.
+# Check the `json` value to find them.
+class GithubError
+ super Error
+ super Serializable
+
+ # The name of the error.
+ var name: String
+
+ # The json content of the error.
+ var json = new JsonObject
+
+ redef init do
+ super
+ json["error"] = name.to_json
+ json["message"] = message.to_json
+ end
+
+ redef fun serialize_to(v) do json.serialize_to v
+
+ redef fun to_s do return "[{name}] {super}"
+end
+
+# Gets the Github token from `git` configuration
+#
# Return the value of `git config --get github.oauthtoken`
-# return "" if no such a key
+# or `""` if no key exists.
fun get_github_oauth: String
do
- var p = new IProcess("git", "config", "--get", "github.oauthtoken")
+ var p = new ProcessReader("git", "config", "--get", "github.oauthtoken")
var token = p.read_line
p.wait
p.close