1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
15 # Nit object oriented interface to Github api.
17 # This modules reifies Github API elements as Nit classes.
19 # For most use-cases you need to use the `GithubAPI` client.
24 # Interface to Github REST API.
26 # Used by all `GithubEntity` to perform requests.
31 # # Get Github authentification token.
32 # var token = get_github_oauth
33 # assert not token.is_empty
36 # var api = new GithubAPI(token)
39 # The API client allows to get Github API entities:
42 # var repo = api.load_repo("privat/nit")
43 # assert repo isa Repo
44 # assert repo.name == "nit"
46 # var user = api.load_user("Morriar")
47 # assert user isa User
48 # assert user.login == "Morriar"
52 # Github API OAuth token.
54 # This token is used to authenticate the application on Github API.
55 # Be aware that there is [rate limits](https://developer.github.com/v3/rate_limit/)
56 # associated to the key.
59 # Github API base url.
61 # Default is `https://api.github.com` and should not be changed.
62 var api_url
= "https://api.github.com"
64 # User agent used for HTTP requests.
66 # Default is `nit_github_api`.
68 # See <https://developer.github.com/v3/#user-agent-required>
69 var user_agent
= "nit_github_api"
73 # Internal Curl instance used to perform API calls.
74 private var ghcurl
: GithubCurl is noinit
78 # * `0`: only errors (default)
80 var verbose_lvl
= 0 is public
writable
83 ghcurl
= new GithubCurl(auth
, user_agent
)
86 # Execute a GET request on Github API.
88 # This method returns raw json data.
89 # See other `get_*` methods to use more expressive types.
91 # var api = new GithubAPI(get_github_oauth)
92 # var obj = api.get("repos/privat/nit")
93 # assert obj isa JsonObject
94 # assert obj["name"] == "nit"
96 # Returns `null` in case of `error`.
98 # obj = api.get("foo/bar/baz")
100 # assert api.was_error
101 # var err = api.last_error
102 # assert err isa GithubError
103 # assert err.name == "GithubAPIError"
104 # assert err.message == "Not Found"
105 fun get
(path
: String): nullable Jsonable do
106 path
= sanitize_uri
(path
)
107 var res
= ghcurl
.get_and_parse
("{api_url}/{path}")
108 if res
isa Error then
117 # Display a message depending on `verbose_lvl`.
118 fun message
(lvl
: Int, message
: String) do
119 if lvl
<= verbose_lvl
then print message
122 # Escape `uri` in an acceptable format for Github.
123 private fun sanitize_uri
(uri
: String): String do
124 # TODO better URI escape.
125 return uri
.replace
(" ", "%20")
128 # Last error occured during Github API communications.
129 var last_error
: nullable Error = null is public
writable
131 # Does the last request provoqued an error?
132 var was_error
= false is protected writable
134 # Load the json object from Github.
135 # See `GithubEntity::load_from_github`.
136 private fun load_from_github
(key
: String): JsonObject do
137 message
(1, "Get {key} (github)")
139 if was_error
then return new JsonObject
140 return res
.as(JsonObject)
143 # Get the Github user with `login`.
145 # Returns `null` if the user cannot be found.
147 # var api = new GithubAPI(get_github_oauth)
148 # var user = api.load_user("Morriar")
149 # assert user.login == "Morriar"
150 fun load_user
(login
: String): nullable User do
151 var user
= new User(self, login
)
152 user
.load_from_github
153 if was_error
then return null
157 # Get the Github repo with `full_name`.
159 # Returns `null` if the repo cannot be found.
161 # var api = new GithubAPI(get_github_oauth)
162 # var repo = api.load_repo("privat/nit")
163 # assert repo.name == "nit"
164 # assert repo.owner.login == "privat"
165 fun load_repo
(full_name
: String): nullable Repo do
166 var repo
= new Repo(self, full_name
)
167 repo
.load_from_github
168 if was_error
then return null
173 # Something returned by the Github API.
175 # Mainly a Nit wrapper around a JSON objet.
176 abstract class GithubEntity
178 # Github API instance.
181 # FIXME constructor should be private
183 # Key used to access this entity from Github api base.
184 fun key
: String is abstract
186 # JSON representation of `self`.
188 # This is the same json structure than used by Github API.
189 var json
: JsonObject is noinit
, protected writable
191 # Load `json` from Github API.
192 private fun load_from_github
do
193 json
= api
.load_from_github
(key
)
196 redef fun to_s
do return json
.to_json
201 # Should be accessed from `GithubAPI::load_user`.
203 # See <https://developer.github.com/v3/users/>.
207 redef var key
is lazy
do return "users/{login}"
212 # Init `self` from a `json` object.
213 init from_json
(api
: GithubAPI, json
: JsonObject) do
214 init(api
, json
["login"].to_s
)
218 # Github User page url.
219 fun html_url
: String do return json
["html_url"].to_s
221 # Avatar image url for this user.
222 fun avatar_url
: String do return json
["avatar_url"].to_s
225 # A Github repository.
227 # Should be accessed from `GithubAPI::load_repo`.
229 # See <https://developer.github.com/v3/repos/>.
233 redef var key
is lazy
do return "repos/{full_name}"
235 # Repo full name on Github.
236 var full_name
: String
238 # Init `self` from a `json` object.
239 init from_json
(api
: GithubAPI, json
: JsonObject) do
240 init(api
, json
["full_name"].to_s
)
244 # Repo short name on Github.
245 fun name
: String do return json
["name"].to_s
247 # Github User page url.
248 fun html_url
: String do return json
["html_url"].to_s
250 # Get the repo owner.
252 return new User.from_json
(api
, json
["owner"].as(JsonObject))