X-Git-Url: http://nitlanguage.org diff --git a/lib/github/github_curl.nit b/lib/github/github_curl.nit index 5e50474..6f28546 100644 --- a/lib/github/github_curl.nit +++ b/lib/github/github_curl.nit @@ -18,15 +18,18 @@ module github_curl 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) @@ -35,14 +38,14 @@ class GithubCurl 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 @@ -50,7 +53,7 @@ class GithubCurl 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 @@ -66,13 +69,77 @@ class GithubCurl 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