Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

[enhance] github: Full v2 API (+1 v3 function)

  • Loading branch information...
commit a63f9239a027534b9e88958bb0da5b1ddd95e013 1 parent 8f5eb7e
Nicolas Glondu authored
View
5 stdlib/apis/github/auth/auth.opa
@@ -4,9 +4,8 @@
This file is part of OPA.
OPA is free software: you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free
- Software Foundation, either version 3 of the License, or (at your option)
- any later version.
+ terms of the GNU Affero General Public License, version 3, as published by
+ the Free Software Foundation.
OPA is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
View
167 stdlib/apis/github/commit/commit.opa
@@ -0,0 +1,167 @@
+/*
+ Copyright © 2011 MLstate
+
+ This file is part of OPA.
+
+ OPA is free software: you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License, version 3, as published by
+ the Free Software Foundation.
+
+ OPA is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
+ more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with OPA. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * Author : Nicolas Glondu <nicolas.glondu@mlstate.com>
+ **/
+
+/**
+ * GitHub commit API module
+ *
+ * @category api
+ * @author Nicolas Glondu, 2011
+ * @destination public
+ */
+
+//package stdlib.apis.github.commit
+import stdlib.apis.github
+import stdlib.apis.github.lib
+
+/* Types returned by API */
+
+type GitHub.commit = {
+ id : string
+ parents : list(string)
+ author : GitHub.commit_user
+ message : string
+ url : string
+ commited_date : Date.date
+ authored_date : Date.date
+ tree : string
+ committer : GitHub.commit_user
+}
+
+type GitHub.commit_more = {
+ base : GitHub.commit
+ modified : list((string,string))
+ removed : list(string)
+}
+
+@private GHCp = {{
+
+ @private GP = GHParse
+
+ get_commit_internal(m) =
+ parents = List.filter_map(
+ j -> match j:RPC.Json.json with
+ | {Record=r} ->
+ match List.assoc("id",r) with
+ | {some={String=s}} -> some(s)
+ | {some=v} -> some(Json.serialize(v))
+ | {none} -> none
+ end
+ | _ -> none,
+ m.list("parents"))
+ { id = m.str("id")
+ parents = parents
+ author = GP.get_commit_user(m.record("author"))
+ message = m.str("message")
+ url = m.str("url")
+ commited_date = m.date("commited_date")
+ authored_date = m.date("authored_date")
+ tree = m.str("tree")
+ committer = GP.get_commit_user(m.record("committer"))
+ } : GitHub.commit
+
+ get_commit(srcmap) =
+ m = GP.map_funs(srcmap)
+ if m.exists("id") then
+ some(get_commit_internal(m))
+ else none
+
+ get_commit_more(srcmap) =
+ m = GP.map_funs(srcmap)
+ if m.exists("id") then
+ base = get_commit_internal(m)
+ removed = m.list("removed")
+ |> List.filter_map(
+ x ->
+ match x with
+ | {String=s} -> some(s)
+ | _ -> none,
+ _ )
+ modified = m.list("modified")
+ |> List.fold(
+ e, acc ->
+ match e:RPC.Json.json with
+ | {Record=r} ->
+ List.fold(
+ (k,v), acc ->
+ vv = match v:RPC.Json.json with
+ | {String=s} -> s
+ | _ -> Json.serialize(v)
+ List.add((k,vv),acc),
+ r, acc
+ )
+ | _ -> acc,
+ _, [])
+ some(~{base modified removed}:GitHub.commit_more)
+ else none
+
+ multiple_commits(res) =
+ GP.dewrap_list(res, "commits", get_commit)
+
+ one_commit_more(res) =
+ GP.dewrap_obj(res, "commit", get_commit_more)
+
+}}
+
+GHCommit = {{
+
+ @private p(o:string,r:string) = "{o}/{r}"
+
+ /**
+ * Gets a list of commits on a branch of a repo
+ *
+ * @param owner Owner of the repo
+ * @param repo Repository to get commits from
+ * @param branch Branch to get commits from
+ * @param page Page of commits displayed. First page is 1. If a value inferior to 1 is provided, it is considered as 1.
+ */
+ get_commits(owner, repo, branch:string, page:int) =
+ path = "/commits/list/{p(owner,repo)}/{branch}"
+ /* Force the min value of page to 1, GitHub also does
+ it on its side anyway. */
+ page = if page < 1 then 1 else page
+ data = [("page",Int.to_string(page))]
+ GHLib.api_get(path, data, GHCp.multiple_commits)
+
+ /**
+ * Gets a list of commit on a file on a branch of a repo
+ *
+ * @param owner Owner of the repo
+ * @param repo Repository to get commits from
+ * @param branch Branch to get commits from
+ * @param file File to follow
+ * @param page Page of commits displayed. First page is 1. If a value inferior to 1 is provided, it is considered as 1.
+ */
+ get_file_commits(owner, repo, branch:string, file:string, page) =
+ path = "/commits/list/{p(owner,repo)}/{branch}/{file}"
+ /* Force the min value of page to 1, GitHub also does
+ it on its side anyway. */
+ page = if page < 1 then 1 else page
+ data = [("page",Int.to_string(page))]
+ GHLib.api_get(path, data, GHCp.multiple_commits)
+
+ /**
+ * Gets detailled information about one commit
+ */
+ get_commit(owner, repo, sha:string) =
+ path = "/commits/show/{p(owner,repo)}/{sha}"
+ GHLib.api_get(path, [], GHCp.one_commit_more)
+
+}}
View
117 stdlib/apis/github/gist/gist.opa
@@ -0,0 +1,117 @@
+/*
+ Copyright © 2011 MLstate
+
+ This file is part of OPA.
+
+ OPA is free software: you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License, version 3, as published by
+ the Free Software Foundation.
+
+ OPA is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
+ more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with OPA. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * Author : Nicolas Glondu <nicolas.glondu@mlstate.com>
+ **/
+
+/**
+ * GitHub gist API module
+ *
+ * @category api
+ * @author Nicolas Glondu, 2011
+ * @destination public
+ */
+
+//package stdlib.apis.github.gist
+import stdlib.apis.github
+import stdlib.apis.github.lib
+
+/* Types returned by API */
+
+type GitHub.gist_comment = {
+ id : int
+ user : string
+ created_at : Date.date
+ updated_at : Date.date
+ body : string
+}
+
+type GitHub.gist = {
+ owner : string
+ public : bool
+ repo : string
+ created_at : Date.date
+ description : string
+ files : list(string)
+ comments : list(GitHub.gist_comment)
+}
+
+@private GHGp = {{
+
+ @private GP = GHParse
+
+ get_comment(srcmap) =
+ m = GP.map_funs(srcmap)
+ { id = m.int("id")
+ user = m.str("user")
+ created_at = m.date("created_at")
+ updated_at = m.date("updated_at")
+ body = m.str("body")
+ } : GitHub.gist_comment
+
+ get_gist(srcmap) =
+ m = GP.map_funs(srcmap)
+ if m.exists("repo") then
+ files = List.map(
+ v -> match v:RPC.Json.json with
+ | {String=s} -> s
+ | _ -> Json.serialize(v),
+ m.list("files"))
+ comments = List.filter_map(
+ v -> match v:RPC.Json.json with
+ | {Record=_} -> some(get_comment(v))
+ | _ -> none,
+ m.list("comments"))
+ res = {
+ owner = m.str("owner")
+ public = m.bool("public")
+ repo = m.str("repo")
+ created_at = m.date("created_at")
+ description = m.str("description")
+ files = files
+ comments = comments
+ } : GitHub.gist
+ some(res)
+ else none
+
+ multiple_gists(res) =
+ GP.dewrap_list(res, "gists", get_gist)
+
+}}
+
+GHGist = {{
+
+ @private host = "https://gist.github.com/api/v1/json"
+
+ get_gist(gist_id:string) =
+ path = "{host}/{gist_id}"
+ r = GHLib.api_get_full(path, [], GHGp.multiple_gists)
+ match r with
+ | {some=l} ->
+ if l == [] then none else some(List.head(l))
+ | _ -> none
+
+ get_user_gists(user:string) =
+ path = "{host}/gists/{user}"
+ GHLib.api_get_full(path, [], GHGp.multiple_gists)
+
+ get_gist_file(gist_id:string, filename:string) =
+ path = "https://raw.github.com/gist/{gist_id}/{filename}"
+ GHLib.api_get_full(path, [], some)
+
+}}
View
40 stdlib/apis/github/github.opa
@@ -31,6 +31,40 @@
/* Types returned by API */
+
+type GitHub.plan = {
+ name : string
+ collaborators : int
+ space : int
+ private_repos : int
+}
+
+type GitHub.user_more = {
+ total_private_repo_count : int
+ collaborators : int
+ disk_usage : int
+ owned_private_repo_count : int
+ private_gist_count : int
+ plan : GitHub.plan
+}
+
+type GitHub.user = {
+ id : int
+ login : string
+ name : string
+ company : string
+ gravatar_id : string
+ created_at : Date.date
+ location : string
+ blog : string
+ public_repo_count : int
+ public_gist_count : int
+ followers_count : int
+ following_count : int
+ user_type : string
+ more : option(GitHub.user_more)
+}
+
type GitHub.repository = {
name : string
owner : string
@@ -56,3 +90,9 @@ type GitHub.public_key = {
id : int
key : string
}
+
+type GitHub.commit_user = {
+ name : string
+ login : string
+ email : string
+}
View
209 stdlib/apis/github/issue/issue.opa
@@ -0,0 +1,209 @@
+/*
+ Copyright © 2011 MLstate
+
+ This file is part of OPA.
+
+ OPA is free software: you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License, version 3, as published by
+ the Free Software Foundation.
+
+ OPA is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
+ more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with OPA. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * Author : Nicolas Glondu <nicolas.glondu@mlstate.com>
+ **/
+
+/**
+ * GitHub issue API module
+ *
+ * @category api
+ * @author Nicolas Glondu, 2011
+ * @destination public
+ */
+
+//package stdlib.apis.github.issue
+import stdlib.apis.github
+import stdlib.apis.github.lib
+
+/* Types returned by API */
+
+type GitHub.issue = {
+ user : string
+ gravatar_id : string
+ created_at : Date.date
+ updated_at : Date.date
+ state : {open}/{closed}
+ number : int
+ votes : int
+ position : float
+ title : string
+ body : string
+ labels : list(string)
+}
+
+type GitHub.issue_comment = {
+ id : int
+ user : string
+ gravatar_id : string
+ created_at : Date.date
+ updated_at : Date.date
+ body : string
+}
+
+@private GHIp = {{
+
+ state_to_string(s) =
+ match s : {open}/{closed} with
+ | {open} -> "open" | {closed} -> "closed"
+
+ @private GP = GHParse
+
+ get_issue(srcmap) =
+ m = GP.map_funs(srcmap)
+ if m.exists("title") then
+ state = match m.str("state") with
+ | "closed" -> {closed}
+ | "open" | _ -> {open}
+ labels = List.filter_map(
+ v -> match v:RPC.Json.json with
+ | {String=s} -> some(s) | _ -> none,
+ m.list("labels"))
+ res = {
+ user = m.str("user")
+ gravatar_id = m.str("gravatar_id")
+ created_at = m.date("created_at")
+ updated_at = m.date("updated_at")
+ state = state
+ number = m.int("number")
+ votes = m.int("votes")
+ position = m.float("position")
+ title = m.str("title")
+ body = m.str("body")
+ labels = labels
+ } : GitHub.issue
+ some(res)
+ else none
+
+ get_comment(srcmap) =
+ m = GP.map_funs(srcmap)
+ if m.exists("id") then
+ res = {
+ id = m.int("id")
+ user = m.str("user")
+ gravatar_id = m.str("gravatar_id")
+ created_at = m.date("created_at")
+ updated_at = m.date("updated_at")
+ body = m.str("body")
+ } : GitHub.issue_comment
+ some(res)
+ else none
+
+ one_issue(res) =
+ GP.dewrap_obj(res, "issue", get_issue)
+
+ multiple_issues(res) =
+ GP.dewrap_list(res, "issues", get_issue)
+
+ one_comment(res) =
+ GP.dewrap_obj(res, "comment", get_comment)
+
+ comments(res) =
+ GP.dewrap_list(res, "comments", get_comment)
+
+ labels(res) = GP.multiple_strings(res, "labels")
+
+}}
+
+GHIssue = {{
+
+ @private p(o:string,r:string) = "{o}/{r}"
+
+ search(owner, repo, state, query:string) =
+ st = GHIp.state_to_string(state)
+ path = "/issues/search/{p(owner,repo)}/{st}/{query}"
+ GHLib.api_get(path, [], GHIp.multiple_issues)
+
+ list_by_state(owner, repo, state) =
+ st = GHIp.state_to_string(state)
+ path = "/issues/list/{p(owner,repo)}/{st}"
+ GHLib.api_get(path, [], GHIp.multiple_issues)
+
+ list_by_label(owner, repo, label:string) =
+ path = "/issues/list/{p(owner,repo)}/label/{label}"
+ GHLib.api_get(path, [], GHIp.multiple_issues)
+
+ get_issue(owner, repo, number:int) =
+ path = "/issues/show/{p(owner,repo)}/{number}"
+ GHLib.api_get(path, [], GHIp.one_issue)
+
+ /**
+ * Opens a new issue
+ *
+ * @param owner Owner of the targeted repo
+ * @param repo Targeted repo
+ * @param title Title of the new issue
+ * @param body Body of the new issue
+ * @param token Access token of user
+ */
+ open_issue(owner, repo, title, body, token) =
+ path = "/issues/open/{p(owner,repo)}"
+ data = [("access_token",token),
+ ("title",title), ("body",body)]
+ GHLib.api_post(path, data, GHIp.one_issue)
+
+ /**
+ * Edits an existing issue
+ *
+ * @param owner Owner of the targeted repo
+ * @param repo Targeted repo
+ * @param number ID number of the issue
+ * @param title New title of the issue (leave blanck to keep old title)
+ * @param body New body of the issue (leave blanck to keep old body)
+ * @param token Access token of user
+ */
+ edit_issue(owner, repo, number:int, title, body, token) =
+ path = "/issues/edit/{p(owner,repo)}/{number}"
+ data = [("access_token",token),
+ ("title",title), ("body",body)]
+ GHLib.api_post(path, data, GHIp.one_issue)
+
+ close_issue(owner, repo, number:int, token) =
+ path = "/issues/close/{p(owner,repo)}/{number}"
+ data = [("access_token",token)]
+ GHLib.api_post(path, data, GHIp.one_issue)
+
+ reopen_issue(owner, repo, number:int, token) =
+ path = "/issues/reopen/{p(owner,repo)}/{number}"
+ data = [("access_token",token)]
+ GHLib.api_post(path, data, GHIp.one_issue)
+
+ list_project_labels(owner, repo) =
+ path = "/issues/labels/{p(owner,repo)}"
+ GHLib.api_get(path, [], GHIp.labels)
+
+ add_label(owner, repo, label:string, number:int, token) =
+ path = "/issues/label/add/{p(owner,repo)}/{label}/{number}"
+ data = [("access_token",token)]
+ GHLib.api_post(path, data, GHIp.labels)
+
+ remove_label(owner, repo, label:string, number:int, token) =
+ path = "/issues/label/remove/{p(owner,repo)}/{label}/{number}"
+ data = [("access_token",token)]
+ GHLib.api_post(path, data, GHIp.labels)
+
+ get_issue_comments(owner, repo, number:int) =
+ path = "/issues/comments/{p(owner,repo)}/{number}"
+ GHLib.api_get(path, [], GHIp.comments)
+
+ comment(owner, repo, number:int, comment, token) =
+ path = "/issues/comment/{p(owner,repo)}/{number}"
+ data = [("access_token",token), ("comment",comment)]
+ GHLib.api_post(path, data, GHIp.one_comment)
+
+}}
View
114 stdlib/apis/github/lib/lib.opa
@@ -4,9 +4,8 @@
This file is part of OPA.
OPA is free software: you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free
- Software Foundation, either version 3 of the License, or (at your option)
- any later version.
+ terms of the GNU Affero General Public License, version 3, as published by
+ the Free Software Foundation.
OPA is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
@@ -57,9 +56,9 @@ GHLib = {{
/* Temporary duplicate while parse functions are built */
- api_get(path, data, parse_fun) =
- final_path = generic_build_path("{host}{path}", data)
- do jlog(final_path)
+ api_get_full(full_path, data, parse_fun) =
+ final_path = generic_build_path(full_path, data)
+ do jlog("GET {final_path}")
match Uri.of_string(final_path) with
| {none} -> none
| {some=uri} ->
@@ -70,6 +69,10 @@ GHLib = {{
parse_fun(s.content)
end
+ api_get(path:string, data, parse_fun) =
+ full_path = "{host}{path}"
+ api_get_full(full_path, data, parse_fun)
+
/**
* Shortcut for GET requests with only a token
*/
@@ -78,9 +81,9 @@ GHLib = {{
else [("access_token", token)]
api_get(path, data, parse_fun)
- full_post(base,path, data, parse_fun) =
+ full_post(base, path, data, parse_fun) =
txtdata = AL.form_urlencode(data)
- do jlog("{base}{path} with {txtdata}")
+ do jlog("POST {txtdata} on {base}{path}")
match Uri.of_string("{base}{path}") with
| {none} -> none
| {some=uri} ->
@@ -100,6 +103,27 @@ GHLib = {{
data = [("access_token", token)]
api_post(path, data, parse_fun)
+ /* For v3 api */
+
+ @private basev3 = "https://api.github.com"
+
+ v3_put(path, data, token:option(string), parse_fun) =
+ txtdata =
+ {Record=data}:RPC.Json.json |> Json.serialize
+ do jlog("PUT {txtdata} on {basev3}{path}")
+ match Uri.of_string("{basev3}{path}") with
+ | {none} -> none
+ | {some=uri} ->
+ options =
+ { WebClient.Put.default_options with
+ auth = Option.map(x->"token {x}", token) }
+ match WebClient.Put.try_put_with_options(uri,txtdata,options) with
+ | {failure=_} -> none
+ | {success=s} ->
+ do jlog(s.content)
+ parse_fun(s.content)
+ end
+
}}
@@ -109,12 +133,12 @@ GHParse = {{
int_of_text(t) = Int.of_string(Text.to_string(t))
n = parser k=[0-9] -> k
nn = parser v=(n+) -> int_of_text(v)
- shift(forward,h,m) =
- h = int_of_text(h)
- min = int_of_text(m)
+ do_shift(forward,h,min) =
d = { Duration.zero with ~forward ~h ~min }
|> Duration.of_human_readable
- Date.advance(_, d)
+ Date.advance(_, d)
+ shift(forward,h,m) =
+ do_shift(forward,int_of_text(h),int_of_text(m))
tmz = parser
| "Z" -> identity
| "-" h=(n n) m=(n n) -> shift(true, h, m)
@@ -129,12 +153,18 @@ GHParse = {{
| y=nn "-" m=nn "-" d=nn "T" h=nn ":" min=nn ":" s=nn tmz=tmz ->
m = Date.Month.of_int(m-1)
tmz(Date.build({year=y month=m day=d h=h min=min s=s}))
- Parser.try_parse(p, str) ? Date.epoch
+ | y=nn "-" m=nn "-" d=nn " " h=nn ":" min=nn ":" s=nn ->
+ m = Date.Month.of_int(m-1)
+ do_shift(true,8,0)(Date.build({year=y month=m day=d h=h min=min s=s}))
+ | y=nn "-" m=nn "-" d=nn ->
+ m = Date.Month.of_int(m-1)
+ do_shift(true,8,0)(Date.build({year=y month=m day=d}))
+ Parser.try_parse(p, str)
map_funs(srcmap) =
map = JsonOpa.record_fields(srcmap) ? Map.empty
str = API_libs_private.map_get_string(_, map)
- date(field) = str(field) |> parse_date
+ date(field) = (str(field) |> parse_date) ? Date.epoch
int = API_libs_private.map_get_int(_, map)
bool = API_libs_private.map_get_bool(_, map, false)
float = API_libs_private.map_get_float(_, map)
@@ -187,6 +217,13 @@ GHParse = {{
/* Parsers used in several sub-libs */
+ get_commit_user(srcmap) =
+ m = map_funs(srcmap)
+ { name = m.str("name")
+ login = m.str("login")
+ email = m.str("email")
+ } : GitHub.commit_user
+
get_public_key(srcmap) =
m = map_funs(srcmap)
if m.exists("key") then
@@ -223,4 +260,53 @@ GHParse = {{
{some=res}
else {none}
+ get_plan(srcmap) =
+ m = map_funs(srcmap)
+ { name = m.str("name")
+ collaborators = m.int("collaborators")
+ space = m.int("space")
+ private_repos = m.int("private_repos")
+ } : GitHub.plan
+
+ get_more(m) =
+ if m.exists("total_private_repo_count") then
+ user_more = {
+ total_private_repo_count = m.int("total_private_repo_count")
+ collaborators = m.int("collaborators")
+ disk_usage = m.int("disk_usage")
+ owned_private_repo_count = m.int("owned_private_repo_count")
+ private_gist_count = m.int("private_gist_count")
+ plan = get_plan(m.record("plan"))
+ } : GitHub.user_more
+ {some=user_more}
+ else {none}
+
+ get_user(srcmap) =
+ m = map_funs(srcmap)
+ if m.exists("id") then
+ id = match m.record("id") with
+ | {Int=i} -> i
+ | {String=s} ->
+ String.explode("-",s) |> List.rev
+ |> List.head |> Int.of_string
+ | _ -> 0
+ res = {
+ id = id
+ login = m.str("login")
+ name = m.str("name")
+ company = m.str("company")
+ gravatar_id = m.str("gravatar_id")
+ created_at = m.date("created_at")
+ location = m.str("location")
+ blog = m.str("blog")
+ public_repo_count = m.int("public_repo_count")
+ public_gist_count = m.int("public_gist_count")
+ followers_count = m.int("followers_count")
+ following_count = m.int("following_count")
+ user_type = m.str("user_type")
+ more = get_more(m)
+ } : GitHub.user
+ {some=res}
+ else {none}
+
}}
View
192 stdlib/apis/github/network/network.opa
@@ -0,0 +1,192 @@
+/*
+ Copyright © 2011 MLstate
+
+ This file is part of OPA.
+
+ OPA is free software: you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License, version 3, as published by
+ the Free Software Foundation.
+
+ OPA is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
+ more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with OPA. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * Author : Nicolas Glondu <nicolas.glondu@mlstate.com>
+ **/
+
+/**
+ * GitHub (secret) network API module
+ *
+ * @category api
+ * @author Nicolas Glondu, 2011
+ * @destination public
+ */
+
+//package stdlib.apis.github.network
+import stdlib.apis.github
+import stdlib.apis.github.lib
+
+/* Types returned by API */
+
+type GitHub.network_user_head = {
+ name : string
+ id : string
+}
+
+type GitHub.network_user = {
+ name : string
+ repo : string
+ heads : list(GitHub.network_user_head)
+}
+
+type GitHub.network_block = {
+ name : string
+ start : int
+ count : int
+}
+
+type GitHub.network_meta = {
+ nethash : string
+ focus : int
+ dates : list(Date.date)
+ users : list(GitHub.network_user)
+ blocks : list(GitHub.network_block)
+ spacemap : list(list(list(int)))
+}
+
+type GitHub.network_commit = {
+ id : string
+ author : string
+ login : string
+ gravatar : string
+ date : Date.date
+ time : int
+ space : int
+ parents : list({index:int}/{hash:string})
+}
+
+@private GHNp = {{
+
+ @private get_sublist(m,name,f) =
+ List.filter_map(
+ v -> match v:RPC.Json.json with
+ | {Record=_} -> some(f(v))
+ | _ -> none,
+ m.list(name))
+
+ @private GP = GHParse
+
+ get_user_head(srcmap) =
+ m = GP.map_funs(srcmap)
+ { name = m.str("name")
+ id = m.str("id")
+ } : GitHub.network_user_head
+
+ get_network_user(srcmap) =
+ m = GP.map_funs(srcmap)
+ heads = get_sublist(m,"heads",get_user_head)
+ { name = m.str("name")
+ repo = m.str("repo")
+ heads = heads
+ } : GitHub.network_user
+
+ get_network_block(srcmap) =
+ m = GP.map_funs(srcmap)
+ { name = m.str("name")
+ start = m.int("start")
+ count = m.int("count")
+ } : GitHub.network_block
+
+ get_network_meta(srcmap) =
+ m = GP.map_funs(srcmap)
+ if m.exists("nethash") then
+ dates = List.filter_map(
+ v -> match v:RPC.Json.json with
+ | {String=s} -> GP.parse_date(s)
+ | _ -> none,
+ m.list("dates"))
+ users = get_sublist(m,"users",get_network_user)
+ blocks = get_sublist(m,"blocks",get_network_block)
+ spacemap = List.filter_map(
+ v0 -> match v0:RPC.Json.json with
+ | {List=l0} ->
+ elt0 = List.filter_map(
+ v1 -> match v1:RPC.Json.json with
+ | {List=l1} ->
+ elt1 = List.filter_map(
+ v2 -> match v2:RPC.Json.json with
+ | {Int=i} -> some(i)
+ | _ -> none,
+ l1)
+ some(elt1)
+ | _ -> none,
+ l0)
+ some(elt0)
+ | _ -> none,
+ m.list("spacemap"))
+ res = {
+ nethash = m.str("nethash")
+ focus = m.int("focus")
+ dates = dates
+ users = users
+ blocks = blocks
+ spacemap = spacemap
+ } : GitHub.network_meta
+ some(res)
+ else none
+
+ get_network_commit(srcmap) =
+ m = GP.map_funs(srcmap)
+ if m.exists("id") then
+ parents = List.filter_map(
+ v -> match v:RPC.Json.json with
+ | {String=s} -> some({hash=s})
+ | {Int=i} -> some({index=i})
+ | _ -> none,
+ m.list("parents"))
+ res = {
+ id = m.str("id")
+ author = m.str("author")
+ login = m.str("login")
+ gravatar = m.str("gravatar")
+ date = m.date("date")
+ time = m.int("time")
+ space = m.int("space")
+ parents = parents
+ } : GitHub.network_commit
+ some(res)
+ else none
+
+ one_meta(res) =
+ match Json.of_string(res) with
+ | {some={Record=r}} ->
+ do jlog("{r}")
+ get_network_meta({Record=r})
+ | _ -> none
+
+ multiple_n_commits(res) =
+ GP.dewrap_list(res, "commits", get_network_commit)
+
+}}
+
+GHNetwork = {{
+
+ get_meta(owner:string,repo:string) =
+ path = "https://github.com/{owner}/{repo}/network_meta"
+ GHLib.api_get_full(path, [], GHNp.one_meta)
+
+ get_data(owner:string, repo:string, nethash:string, start:int, stop:int) =
+ path = "https://github.com/{owner}/{repo}/network_data_chunk"
+ data = [("nethash",nethash)]
+ |> (if start < 0 then identity
+ else List.add(("start",Int.to_string(start)), _))
+ |> (if stop < 0 then identity
+ else List.add(("end",Int.to_string(stop)), _))
+ GHLib.api_get_full(path, data, GHNp.multiple_n_commits)
+
+}}
View
151 stdlib/apis/github/object/object.opa
@@ -0,0 +1,151 @@
+/*
+ Copyright © 2011 MLstate
+
+ This file is part of OPA.
+
+ OPA is free software: you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License, version 3, as published by
+ the Free Software Foundation.
+
+ OPA is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
+ more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with OPA. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * Author : Nicolas Glondu <nicolas.glondu@mlstate.com>
+ **/
+
+/**
+ * GitHub commit API module
+ *
+ * @category api
+ * @author Nicolas Glondu, 2011
+ * @destination public
+ */
+
+//package stdlib.apis.github.object
+import stdlib.apis.github
+import stdlib.apis.github.lib
+
+/* Types returned by API */
+
+type GitHub.tree_meta = {
+ sha : string
+ name : string
+ size : int
+ mime_type : string
+ mode : string
+ node_type : {tree}/{blob}/{other:string}
+}
+
+type GitHub.blob = {
+ meta : GitHub.tree_meta
+ data : string
+}
+
+@private GHOp = {{
+
+ @private GP = GHParse
+
+ get_tree_meta_inner(m) =
+ node_type = match m.str("type") with
+ | "tree" -> {tree}
+ | "blob" -> {blob}
+ | other -> ~{other}
+ { sha = m.str("sha")
+ name = m.str("name")
+ size = m.int("size")
+ mime_type = m.str("mime_type")
+ mode = m.str("mode")
+ node_type = node_type
+ } : GitHub.tree_meta
+
+ get_tree_meta(srcmap) =
+ m = GP.map_funs(srcmap)
+ if m.exists("sha") then
+ some(get_tree_meta_inner(m))
+ else none
+
+ get_blob(srcmap) =
+ m = GP.map_funs(srcmap)
+ if m.exists("sha") then
+ meta = {get_tree_meta_inner(m) with node_type = {blob}}
+ res = {
+ meta = meta
+ data = m.str("data")
+ } : GitHub.blob
+ some(res)
+ else none
+
+ get_blob_meta(srcmap) =
+ m = GP.map_funs(srcmap)
+ if m.exists("sha") then
+ some({get_tree_meta_inner(m) with node_type = {blob}})
+ else none
+
+ get_blobs(srcmap) =
+ match srcmap with
+ | {Record=r} ->
+ res = List.map(
+ (k,v) -> match v:RPC.Json.json with
+ | {String=s} -> (k,s)
+ | _ -> (k,Json.serialize(v)),
+ r)
+ some(res)
+ | _ -> none
+
+ multiple_metas(res) =
+ GP.dewrap_list(res, "tree", get_tree_meta)
+
+ one_blob_meta(res) =
+ GP.dewrap_obj(res, "blob", get_blob_meta)
+
+ one_blob(res) =
+ GP.dewrap_obj(res, "blob", get_blob)
+
+ text_blobs(res) =
+ GP.dewrap_obj(res, "blobs", get_blobs)
+
+ full_blobs(res) =
+ GP.dewrap_list(res, "blobs", get_blob_meta)
+
+}}
+
+GHObject = {{
+
+ @private p(o:string,r:string) = "{o}/{r}"
+
+ get_tree(owner, repo, tree_sha:string) =
+ path = "/tree/show/{p(owner,repo)}/{tree_sha}"
+ GHLib.api_get(path, [], GHOp.multiple_metas)
+
+ get_recursive_tree(owner, repo, tree_sha:string) =
+ path = "/tree/full/{p(owner,repo)}/{tree_sha}"
+ GHLib.api_get(path, [], GHOp.multiple_metas)
+
+ get_blob_meta(owner, repo, tree_sha:string, file:string) =
+ path = "/blob/show/{p(owner,repo)}/{tree_sha}/{file}"
+ data = [("meta","1")]
+ GHLib.api_get(path, data, GHOp.one_blob_meta)
+
+ get_blob(owner, repo, tree_sha:string, file:string) =
+ path = "/blob/show/{p(owner,repo)}/{tree_sha}/{file}"
+ GHLib.api_get(path, [], GHOp.one_blob)
+
+ get_all_blobs(owner, repo, tree_sha:string) =
+ path = "/blob/all/{p(owner,repo)}/{tree_sha}"
+ GHLib.api_get(path, [], GHOp.text_blobs)
+
+ get_all_full_blobs(owner, repo, tree_sha:string) =
+ path = "/blob/full/{p(owner,repo)}/{tree_sha}"
+ GHLib.api_get(path, [], GHOp.full_blobs)
+
+ get_raw_blob(owner, repo, tree:string) =
+ path = "/blob/show/{p(owner,repo)}/{tree}"
+ GHLib.api_get(path, [], some)
+
+}}
View
254 stdlib/apis/github/orgs/orgs.opa
@@ -0,0 +1,254 @@
+/*
+ Copyright © 2011 MLstate
+
+ This file is part of OPA.
+
+ OPA is free software: you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License, version 3, as published by
+ the Free Software Foundation.
+
+ OPA is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
+ more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with OPA. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * Author : Nicolas Glondu <nicolas.glondu@mlstate.com>
+ **/
+
+/**
+ * GitHub organization API module
+ *
+ * @category api
+ * @author Nicolas Glondu, 2011
+ * @destination public
+ */
+
+//package stdlib.apis.github.orgs
+import stdlib.apis.github
+import stdlib.apis.github.lib
+
+type GHOrgs.value =
+ { name : string }
+ / { email : string }
+ / { blog : string }
+ / { company : string }
+ / { location : string }
+ / { billing_email : string }
+
+/* Types returned by API */
+
+type GitHub.organization = {
+ name : string
+ login : string
+ company : string
+ email : string
+ gravatar_id : string
+ location : string
+ created_at : Date.date
+ blog : string
+ public_gist_count : int
+ public_repo_count : int
+ id : int
+ org_type : string
+ followers_count : string
+// permission : ??
+}
+
+type GitHub.permission = {admin} / {push} / {pull}
+
+type GitHub.team = {
+ name : string
+ id : int
+ permission : GitHub.permission
+}
+
+@private GHOp = {{
+
+ explode_orgs_values(v) =
+ ( match v : GHOrgs.value with
+ | ~{name} -> ("name",name)
+ | ~{email} -> ("email",email)
+ | ~{blog} -> ("blog",blog)
+ | ~{company} -> ("company",company)
+ | ~{location} -> ("location",location)
+ | ~{billing_email} -> ("billing_email",billing_email)
+ ) |> (a:string,b:string) -> ("organization[{a}]",b)
+
+ perm_to_str(p) =
+ match p : GitHub.permission with
+ | {admin} -> "admin"
+ | {push} -> "push"
+ | {pull} -> "pull"
+
+ perm_from_str(p) : GitHub.permission =
+ match p : string with
+ | "admin" -> {admin}
+ | "push" -> {push}
+ | "pull" -> {pull}
+ | _ -> {pull}
+
+ @private GP = GHParse
+
+ get_org(srcmap) =
+ m = GP.map_funs(srcmap)
+ if m.exists("gravatar_id") then
+ res = {
+ name = m.str("name")
+ login = m.str("login")
+ company = m.str("company")
+ email = m.str("email")
+ gravatar_id = m.str("gravatar_id")
+ location = m.str("location")
+ created_at = m.date("created_at")
+ blog = m.str("blog")
+ public_gist_count = m.int("public_gist_count")
+ public_repo_count = m.int("public_repo_count")
+ id = m.int("id")
+ org_type = m.str("org_type")
+ followers_count = m.str("followers_count")
+ } : GitHub.organization
+ some(res)
+ else none
+
+ get_team(srcmap) =
+ m = GP.map_funs(srcmap)
+ if m.exists("name") then
+ res = {
+ name = m.str("name")
+ id = m.int("id")
+ permission = m.str("permission") |> perm_from_str
+ } : GitHub.team
+ some(res)
+ else none
+
+ one_org(res) =
+ GP.dewrap_obj(res, "organizations", get_org)
+
+ multiple_orgs(res) =
+ GP.dewrap_list(res, "organizations", get_org)
+
+ multiple_repos(res) =
+ GP.dewrap_list(res, "repositories", GP.get_repo(false))
+
+ multiple_users(res) =
+ GP.dewrap_list(res, "users", GP.get_user)
+
+ one_team(res) =
+ GP.dewrap_obj(res, "team", get_team)
+
+ multiple_teams(res) =
+ GP.dewrap_list(res, "teams", get_team)
+
+}}
+
+GHOrgs = {{
+
+ show(org:string) =
+ path = "/organizations/{org}"
+ GHLib.api_get(path, [], GHOp.one_org)
+
+ update(org:string, updates, token) =
+ path = "/organizations/{org}"
+ data = List.map(GHOp.explode_orgs_values, updates)
+ |> List.add(("access_token", token), _)
+ GHLib.api_post(path, data, GHOp.one_org)
+
+ get_user_organizations(user:string) =
+ path = "/user/show/{user}/organizations"
+ GHLib.api_get(path, [], GHOp.multiple_orgs)
+
+ get_current_user_organizations(token) =
+ path = "/organizations"
+ GHLib.api_get_logged(path, token, GHOp.multiple_orgs)
+
+ /**
+ * List all repositories across all the organizations
+ * that you can access.
+ *
+ * @param inc_all_owned If [false], returns all repos that current user can explicitly access through teams. If [true], adds all repos from all organizations owned by user.
+ * @param inc_public If [true], adds public repos from organizations that current user has no explicit access to.
+ * @param token User token
+ */
+ get_current_user_repos(inc_all_owned, inc_public, token) =
+ path = "/organizations/repositories"
+ data = [("access_token",token)]
+ |> (if inc_all_owned then List.add(("owned","1"), _)
+ else identity)
+ |> (if inc_public then List.add(("public","1"), _)
+ else identity)
+ GHLib.api_get(path, data, GHOp.multiple_repos)
+
+ get_org_owners(org:string, token) =
+ path = "/organizations/{org}/owners"
+ GHLib.api_get_logged(path, token, GHOp.multiple_users)
+
+ get_org_public_members(org:string) =
+ path = "/organizations/{org}/public_members"
+ GHLib.api_get(path, [], GHOp.multiple_users)
+
+ get_org_public_repos(org:string) =
+ path = "/organizations/{org}/public_repositories"
+ GHLib.api_get(path, [], GHOp.multiple_repos)
+
+
+ get_teams(org:string, token) =
+ path = "/organizations/{org}/teams"
+ GHLib.api_get_logged(path, token, GHOp.multiple_teams)
+
+ create_team(org:string, name, permission, repos, token) =
+ path = "/organizations/{org}/teams"
+ repos = List.map(
+ ((a:string,b:string)-> ("team[repo_names][]","{a}/{b}")),
+ repos)
+ data =
+ [("access_token",token), ("team[name]",name),
+ ("team[permission]",GHOp.perm_to_str(permission))]
+ |> List.append(repos,_)
+ GHLib.api_post(path, data, GHOp.one_team)
+
+ get_team(id:int, token) =
+ path = "/teams/{id}"
+ GHLib.api_get_logged(path, token, GHOp.one_team)
+
+ /* Uncertain: TESTME */
+ del_team(id:int, token) =
+ path = "/teams/{id}/delete"
+ data = [("access_token",token)]
+ GHLib.api_post(path, data, some)
+
+ get_team_members(id:int, token) =
+ path = "/teams/{id}/members"
+ GHLib.api_get_logged(path, token, some)
+
+ add_team_member(id:int, name, token) =
+ path = "/teams/{id}/members"
+ data = [("access_token",token),("name",name)]
+ GHLib.api_post(path, data, some)
+
+ /* Uncertain: TESTME */
+ remove_team_member(id:int, name, token) =
+ path = "/teams/{id}/members/delete"
+ data = [("access_token",token),("name",name)]
+ GHLib.api_post(path, data, some)
+
+
+ get_team_repos(id:int, token) =
+ path = "/teams/{id}/repositories"
+ GHLib.api_get_logged(path, token, GHOp.multiple_repos)
+
+ add_team_repo(id:int, owner:string, repo:string, token) =
+ path = "/teams/{id}/repositories"
+ data = [("access_token",token),("name","{owner}/{repo}")]
+ GHLib.api_post(path, data, some)
+
+ /* Uncertain: TESTME */
+ remove_team_repo(id:int, owner:string, repo:string, token) =
+ path = "/teams/{id}/repositories/delete"
+ data = [("access_token",token),("name","{owner}/{repo}")]
+ GHLib.api_post(path, data, some)
+
+}}
View
197 stdlib/apis/github/pull/pull.opa
@@ -4,9 +4,8 @@
This file is part of OPA.
OPA is free software: you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free
- Software Foundation, either version 3 of the License, or (at your option)
- any later version.
+ terms of the GNU Affero General Public License, version 3, as published by
+ the Free Software Foundation.
OPA is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
@@ -45,10 +44,11 @@ type GitHub.user_simple = {
login : string
name : string
gravatar_id : string
+ company : string
user_type : string
}
-type GitHub.commit = {
+type GitHub.ref = {
label : string
ref : string
sha : string
@@ -65,8 +65,8 @@ type GitHub.pull_req = {
state : {open}/{closed:Date.date}/{other:string}
position : float
number : int
- head : GitHub.commit
- base : GitHub.commit
+ head : GitHub.ref
+ base : GitHub.ref
gravatar_id : string
diff_url : string
html_url : string
@@ -76,8 +76,40 @@ type GitHub.pull_req = {
created_at : Date.date
updated_at : Date.date
merged_at : Date.date
-// labels : list(string) ???
-// mergeable : string ???
+ labels : list(string)
+ mergeable : bool
+}
+
+type GitHub.discussion_elt =
+ { commit_id : string
+ committed_date : Date.date
+ authored_date : Date.date
+ user : GitHub.user_simple
+ author : GitHub.user_simple
+ parents : list(list((string,string)))
+ message : string
+ committer : GitHub.commit_user
+ tree : string }
+/ { comment_id : int
+ gravatar_id : string
+ user : GitHub.user_simple
+ created_at : Date.date
+ updated_at : Date.date
+ body : string }
+/ { review_pos : int
+ diff_hunk : string
+ user : GitHub.user_simple
+ commit_id : string
+ created_at : Date.date
+ updated_at : Date.date
+ path : string
+ body : string }
+
+
+type GitHub.full_pull_req = {
+ infos : GitHub.pull_req
+ discussion : list(GitHub.discussion_elt)
+ issue_user : GitHub.user_simple
}
@private GHPp = {{
@@ -89,10 +121,11 @@ type GitHub.pull_req = {
{ login = m.str("login")
name = m.str("name")
gravatar_id = m.str("gravatar_id")
- user_type = m.str("user_type")
+ company = m.str("company")
+ user_type = m.str("type")
} : GitHub.user_simple
- get_commit(srcmap) =
+ get_ref(srcmap) =
m = GP.map_funs(srcmap)
{ label = m.str("label")
ref = m.str("ref")
@@ -100,42 +133,114 @@ type GitHub.pull_req = {
repository = m.record("repository")
|> GP.get_repo(true) |> Option.get
user = get_user_simple(m.record("user"))
- } : GitHub.commit
+ } : GitHub.ref
+
+ get_pull_req_int(m) =
+ state = match m.str("state") with
+ | "open" -> {open}
+ | "closed" -> {closed=m.date("closed_at")}
+ | x -> {other=x}
+ labels = List.filter_map(
+ v -> match v:RPC.Json.json with
+ | {String=s} -> some(s)
+ | _ -> none,
+ m.list("labels"))
+ { title = m.str("title")
+ body = m.str("body")
+ user = get_user_simple(m.record("user"))
+ comments = m.int("comments")
+ votes = m.int("votes")
+ state = state
+ position = m.float("position")
+ number = m.int("number")
+ head = get_ref(m.record("head"))
+ base = get_ref(m.record("base"))
+ gravatar_id = m.str("gravatar_id")
+ diff_url = m.str("diff_url")
+ html_url = m.str("html_url")
+ patch_url = m.str("patch_url")
+ issue_created_at = m.date("issue_created_at")
+ issue_updated_at = m.date("issue_updated_at")
+ created_at = m.date("created_at")
+ updated_at = m.date("updated_at")
+ merged_at = m.date("merged_at")
+ labels = labels
+ mergeable = m.bool("mergeable")
+ } : GitHub.pull_req
get_pull_req(srcmap) =
m = GP.map_funs(srcmap)
if m.exists("state") then
- state = match m.str("state") with
- | "open" -> {open}
- | "closed" -> {closed=m.date("closed_at")}
- | x -> {other=x}
+ some(get_pull_req_int(m))
+ else none
+
+ get_discussion_elt(srcmap) : option(GitHub.discussion_elt) =
+ m = GP.map_funs(srcmap)
+ match m.str("type") with
+ | "Commit" ->
+ parents = List.filter_map(
+ v -> match v:RPC.Json.json with
+ | {Record=r} ->
+ List.map(
+ (k,v1) -> match v1:RPC.Json.json with
+ | {String=s} -> (k,s)
+ | _ -> (k,Json.serialize(v1)),
+ r) |> some
+ | _ -> none,
+ m.list("parents"))
+ { commit_id = m.str("id")
+ committed_date = m.date("committed_date")
+ authored_date = m.date("authored_date")
+ user = get_user_simple(m.record("user"))
+ author = get_user_simple(m.record("author"))
+ parents = parents
+ message = m.str("message")
+ committer = GP.get_commit_user(m.record("committer"))
+ tree = m.str("tree")
+ } |> some
+ | "IssueComment" ->
+ { comment_id = m.int("comment_id")
+ gravatar_id = m.str("gravatar_id")
+ user = get_user_simple(m.record("user"))
+ created_at = m.date("created_at")
+ updated_at = m.date("updated_at")
+ body = m.str("body")
+ } |> some
+ | "PullRequestReviewComment" ->
+ { review_pos = m.int("review_pos")
+ diff_hunk = m.str("diff_hunk")
+ user = get_user_simple(m.record("user"))
+ commit_id = m.str("commit_id")
+ created_at = m.date("created_at")
+ updated_at = m.date("updated_at")
+ path = m.str("path")
+ body = m.str("body")
+ } |> some
+ | _ -> none
+
+ get_full_pull_req(srcmap) =
+ m = GP.map_funs(srcmap)
+ if m.exists("state") then
+ infos = get_pull_req_int(m)
+ discussion = List.filter_map(
+ v -> match v : RPC.Json.json with
+ | {Record=_} -> get_discussion_elt(v)
+ | _ -> none,
+ m.list("discussion"))
res = {
- title = m.str("title")
- body = m.str("body")
- user = get_user_simple(m.record("user"))
- comments = m.int("comments")
- votes = m.int("votes")
- state = state
- position = m.float("position")
- number = m.int("number")
- head = get_commit(m.record("head"))
- base = get_commit(m.record("base"))
- gravatar_id = m.str("gravatar_id")
- diff_url = m.str("diff_url")
- html_url = m.str("html_url")
- patch_url = m.str("patch_url")
- issue_created_at = m.date("issue_created_at")
- issue_updated_at = m.date("issue_updated_at")
- created_at = m.date("created_at")
- updated_at = m.date("updated_at")
- merged_at = m.date("merged_at")
- } : GitHub.pull_req
- {some=res}
+ infos = infos
+ discussion = discussion
+ issue_user = get_user_simple(m.record("issue_user"))
+ } : GitHub.full_pull_req
+ some(res)
else none
pull_requests(res) =
GP.dewrap_list(res, "pulls", get_pull_req)
+ one_full_pull_request(res) =
+ GP.dewrap_obj(res, "pull", get_full_pull_req)
+
}}
GHPull = {{
@@ -152,23 +257,27 @@ GHPull = {{
[("access_token", token), ("pull[base]", params.base),
("pull[head]", params.head)]
|> List.append(d,_)
- GHLib.api_post(path, data, some)
+ GHLib.api_post(path, data, GHPp.one_full_pull_request)
- @private generic_pull(owner, repo, more:string, token:option(string)) =
+ @private generic_pull(owner, repo, more:string, token:option(string), f) =
path = "/pulls/{p(owner,repo)}/{more}"
match token with
- | {none} ->
- GHLib.api_get(path, [], GHPp.pull_requests)
- | {some=t} ->
- GHLib.api_get_logged(path, t, GHPp.pull_requests)
+ | {none} -> GHLib.api_get(path, [], f)
+ | {some=t} -> GHLib.api_get_logged(path, t, f)
list(owner, repo, state:{open}/{closed}, token:option(string)) =
st = match state with
| {open} -> "open"
| {closed} -> "closed"
- generic_pull(owner, repo, st, token)
+ generic_pull(owner, repo, st, token, GHPp.pull_requests)
number(owner, repo, number:int, token:option(string)) =
- generic_pull(owner, repo, Int.to_string(number), token)
+ generic_pull(owner, repo, Int.to_string(number),
+ token, GHPp.one_full_pull_request)
+
+ merge(owner, repo, number:int, token) =
+ path = "/repos/{p(owner,repo)}/pulls/{number}/merge"
+ data = []
+ GHLib.v3_put(path, data, some(token), some)
}}
View
5 stdlib/apis/github/repos/repos.opa
@@ -4,9 +4,8 @@
This file is part of OPA.
OPA is free software: you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free
- Software Foundation, either version 3 of the License, or (at your option)
- any later version.
+ terms of the GNU Affero General Public License, version 3, as published by
+ the Free Software Foundation.
OPA is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
View
93 stdlib/apis/github/user/user.opa
@@ -4,9 +4,8 @@
This file is part of OPA.
OPA is free software: you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free
- Software Foundation, either version 3 of the License, or (at your option)
- any later version.
+ terms of the GNU Affero General Public License, version 3, as published by
+ the Free Software Foundation.
OPA is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
@@ -39,99 +38,15 @@ type GHUser.t =
{ self : string } /** Token of user - provides more information */
/ { login : string } /** Login of user */
-/* Types returned by API */
-
-type GitHub.plan = {
- name : string
- collaborators : int
- space : int
- private_repos : int
-}
-
-type GitHub.user_more = {
- total_private_repo_count : int
- collaborators : int
- disk_usage : int
- owned_private_repo_count : int
- private_gist_count : int
- plan : GitHub.plan
-}
-
-type GitHub.user = {
- id : int
- login : string
- name : string
- company : string
- gravatar_id : string
- created_at : Date.date
- location : string
- blog : string
- public_repo_count : int
- public_gist_count : int
- followers_count : int
- following_count : int
- user_type : string
- more : option(GitHub.user_more)
-}
-
@private GHUp = {{
@private GP = GHParse
- get_plan(srcmap) =
- m = GP.map_funs(srcmap)
- { name = m.str("name")
- collaborators = m.int("collaborators")
- space = m.int("space")
- private_repos = m.int("private_repos")
- } : GitHub.plan
-
- get_more(m) =
- if m.exists("total_private_repo_count") then
- user_more = {
- total_private_repo_count = m.int("total_private_repo_count")
- collaborators = m.int("collaborators")
- disk_usage = m.int("disk_usage")
- owned_private_repo_count = m.int("owned_private_repo_count")
- private_gist_count = m.int("private_gist_count")
- plan = get_plan(m.record("plan"))
- } : GitHub.user_more
- {some=user_more}
- else {none}
-
- get_user(srcmap) =
- m = GP.map_funs(srcmap)
- if m.exists("id") then
- id = match m.record("id") with
- | {Int=i} -> i
- | {String=s} ->
- String.explode("-",s) |> List.rev
- |> List.head |> Int.of_string
- | _ -> 0
- res = {
- id = id
- login = m.str("login")
- name = m.str("name")
- company = m.str("company")
- gravatar_id = m.str("gravatar_id")
- created_at = m.date("created_at")
- location = m.str("location")
- blog = m.str("blog")
- public_repo_count = m.int("public_repo_count")
- public_gist_count = m.int("public_gist_count")
- followers_count = m.int("followers_count")
- following_count = m.int("following_count")
- user_type = m.str("user_type")
- more = get_more(m)
- } : GitHub.user
- {some=res}
- else {none}
-
one_full_user(res) =
- GP.dewrap_obj(res, "user", get_user)
+ GP.dewrap_obj(res, "user", GP.get_user)
multiple_full_users(res) =
- GP.dewrap_list(res, "users", get_user)
+ GP.dewrap_list(res, "users", GP.get_user)
multiple_users_ids(res) =
GP.multiple_strings(res, "users")
Please sign in to comment.
Something went wrong with that request. Please try again.