From b55e915da97bb461bad6c5380f7739658292142b Mon Sep 17 00:00:00 2001 From: Ian Smith Date: Sun, 14 Apr 2013 15:30:01 -0700 Subject: [PATCH 1/3] Added support for user detail structs and for repository objects (with detail structs) --- client/client.go | 3 ++ client/result.go | 29 +++++++++++-- users/users.go | 108 +++++++++++++++++++++++++++-------------------- 3 files changed, 90 insertions(+), 50 deletions(-) diff --git a/client/client.go b/client/client.go index d0bc119..b79b589 100644 --- a/client/client.go +++ b/client/client.go @@ -8,6 +8,7 @@ import ( "errors" "io" "net/http" + "fmt" ) const ghBaseApiUrl = "https://api.github.com/" @@ -84,6 +85,8 @@ func (ghc *GithubClient) RunRequest(req *http.Request, httpc *http.Client) (res return } + fmt.Printf("REQ %+v\n\n",req) + fmt.Printf("RESP %+v\n\n",resp) res = newGithubResult(ghc, resp) return diff --git a/client/result.go b/client/result.go index f59cbba..ff40b72 100644 --- a/client/result.go +++ b/client/result.go @@ -8,6 +8,7 @@ import ( "encoding/json" "io/ioutil" "net/http" + _ "fmt" ) /* @@ -48,7 +49,7 @@ func (r *GithubResult) IsSuccess() bool { return r.RawHttpResponse.StatusCode == 200 } -func (r *GithubResult) parseBody() (err error) { +func (r *GithubResult) parseBody(in interface{}) (err error) { if r.RawHttpResponse.ContentLength == 0 { // EMPTY OBJECT err = json.Unmarshal(([]byte)("[]"), &(r.jsonBody)) @@ -59,8 +60,15 @@ func (r *GithubResult) parseBody() (err error) { if err != nil { return err } - - r.jsonParseError = json.Unmarshal(data, &(r.jsonBody)) + + if in!=nil { + r.jsonParseError = json.Unmarshal(data, in) + if r.jsonParseError==nil { + r.jsonBody = in + } + } else { + r.jsonParseError = json.Unmarshal(data, &(r.jsonBody)) + } err = r.jsonParseError } @@ -76,10 +84,23 @@ func (r *GithubResult) parseHeader() { return } +//Parse body into a pointer to the appropriate struct +func (r *GithubResult) JsonStruct(in interface{}) (j interface{}, err error) { + if r.jsonBody == nil && r.jsonParseError == nil { + err = r.parseBody(in) + + if err != nil { + r.jsonParseError = err + return + } + } + + return r.jsonBody, r.jsonParseError +} // Lazily parse body as json and return unmarshalled results. func (r *GithubResult) Json() (j interface{}, err error) { if r.jsonBody == nil && r.jsonParseError == nil { - err = r.parseBody() + err = r.parseBody(nil) if err != nil { r.jsonParseError = err diff --git a/users/users.go b/users/users.go index 52017e0..4a36ab6 100644 --- a/users/users.go +++ b/users/users.go @@ -9,6 +9,54 @@ import ( "net/http" ) +type PlanDetail struct { + Name string + Space int + Collaborators int + Private_repos int +} + +type UserShort struct { + Login string + Id int + Avatar_url string + Gravatar_id string + Url string +} + +type UserDetail struct { + Id int + Login string + Avatar_url string + Gravatar_id string + Url string + Received_events_url string + Type string + Following int + Site_admin bool + Followers_url string + Created_at string + Plan *PlanDetail + Following_url string + Organizations_url string + Events_url string + Updated_at string + Private_gists int + Gists_url string + Starred_url string + Subscriptions_url string + Disk_usage int + Html_url string + Repos_url string + Followers int + Public_gists int + Total_private_repos int + Owned_private_repos int + Collaborators int + Public_repos int + Fork bool +} + // Users is a simplified github users api client. type Users struct { *ghclient.GithubClient @@ -18,72 +66,40 @@ type Users struct { func NewUsers(ghc *ghclient.GithubClient) *Users { userc := new(Users) userc.GithubClient = ghc - return userc } // Request the current autenticated user info. -// It returns a GithubResult and an error. -func (ghc *Users) GetAuthenticatedUserInfo() (res *ghclient.GithubResult, err error) { +// It returns a UserDetail and an error. +func (ghc *Users) GetAuthenticatedUserInfo() (*UserDetail, error) { req, err := ghc.NewAPIRequest("GET", "user", nil) if err != nil { - return + return nil, err } httpc := new(http.Client) + res, err := ghc.RunRequest(req, httpc) - res, err = ghc.RunRequest(req, httpc) - - return + var detail UserDetail + _, err = res.JsonStruct(&detail) + return &detail, err } // Request github user info about a defined username. -// It returns a GithubResult and an error. -func (ghc *Users) GetUserInfo(username string) (res *ghclient.GithubResult, err error) { +// It returns a UserDetail and an error. +func (ghc *Users) GetUserInfo(username string) (*UserDetail, error) { req, err := ghc.NewAPIRequest("GET", "users/"+username, nil) if err != nil { - return + return nil, err } httpc := new(http.Client) - res, err = ghc.RunRequest(req, httpc) - - return -} + res, err := ghc.RunRequest(req, httpc) -// TODO: patch user info -/* -Update the authenticated user - -PATCH /user - -Input - -name - Optional string -email - Optional string - Publicly visible email address. -blog - Optional string -company - Optional string -location - Optional string -hireable - Optional boolean -bio - Optional string - -{ - "name": "monalisa octocat", - "email": "octocat@github.com", - "blog": "https://github.com/blog", - "company": "GitHub", - "location": "San Francisco", - "hireable": true, - "bio": "There once..." + var detail UserDetail + _, err = res.JsonStruct(&detail) + return &detail, err } -*/ From d4f68feed649b249bcfce3eeb1da81602cbb5861 Mon Sep 17 00:00:00 2001 From: Ian Smith Date: Sun, 14 Apr 2013 15:50:52 -0700 Subject: [PATCH 2/3] forgot to add new repos file --- repos/repos.go | 103 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 repos/repos.go diff --git a/repos/repos.go b/repos/repos.go new file mode 100644 index 0000000..a344f0d --- /dev/null +++ b/repos/repos.go @@ -0,0 +1,103 @@ +// Copyright 2012 Alca Società Cooperativa. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package repos + +import ( + ghclient "github.com/alcacoop/go-github-client/client" + ghuser "github.com/alcacoop/go-github-client/users" + "fmt" + "net/http" +) + + +type RepoDetail struct { + Id int + Url string + Html_url string + Clone_url string + Git_url string + Ssh_url string + Svn_url string + Mirror_url string + Parent *RepoDetail + Source *RepoDetail + Owner *ghuser.UserShort + Name string + Full_name string + Description string + Homepage string + Language string + Private bool + Fork bool + Forks int + Hireable bool + Watchers int + Size int + Master_branch string + Open_issues int + Pushed_at string + Created_at string + Updated_at string +} + +// Repos is a simplified github repos api client. +type Repos struct { + *ghclient.GithubClient + login string +} + +// create a new github Repos client from an existent GithubClient +func NewRepos(ghc *ghclient.GithubClient) *Repos { + repoc := new(Repos) + repoc.GithubClient = ghc + return repoc +} + +func (self *Repos) readLogin() (error) { + if self.login!="" { + return nil + } + users := ghuser.NewUsers(self.GithubClient) + userDetail, err := users.GetAuthenticatedUserInfo() + if err!=nil { + return err + } + self.login = userDetail.Login + return nil +} + +// Request the current autenticated user's repos. +// It returns a RepoDetail, the ghclient.Result (for pagination info) and an error. +func (self *Repos) GetAuthenticatedUserRepos() ([]*RepoDetail, *ghclient.GithubResult, error) { + + req, err := self.NewAPIRequest("GET", "user/repos", nil) + if err != nil { + return nil, nil, err + } + httpc := new(http.Client) + res, err := self.RunRequest(req, httpc) + + detail := []*RepoDetail{} + _, err = res.JsonStruct(&detail) + return detail, res, err + +} + +func (self *Repos) GetAuthenticatedUserPublicInfo(name string) (*RepoDetail, error) { + err := self.readLogin() + if err != nil { + return nil, err + } + req, err := self.NewAPIRequest("GET", fmt.Sprintf("repos/%s/%s", self.login, name), nil) + if err != nil { + return nil, err + } + httpc := new(http.Client) + res, err := self.RunRequest(req, httpc) + + var detail RepoDetail + _, err = res.JsonStruct(&detail) + return &detail, err +} From 0c4133dec5651cbe49bdfa70c8aa13038189a7d6 Mon Sep 17 00:00:00 2001 From: Ian Smith Date: Sun, 14 Apr 2013 16:01:41 -0700 Subject: [PATCH 3/3] converted imports to use my forked repo --- examples/gh_create_gist/main.go | 4 ++-- examples/gh_get_gistslist/main.go | 4 ++-- examples/gh_get_issueslist/main.go | 4 ++-- issues/issue.go | 2 +- issues/issues.go | 2 +- issues/list.go | 2 +- repos/repos.go | 4 ++-- users/users.go | 2 +- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/examples/gh_create_gist/main.go b/examples/gh_create_gist/main.go index dd17eac..e20b801 100644 --- a/examples/gh_create_gist/main.go +++ b/examples/gh_create_gist/main.go @@ -7,8 +7,8 @@ package main import ( "flag" "fmt" - ghclient "github.com/alcacoop/go-github-client/client" - ghgists "github.com/alcacoop/go-github-client/gists" + ghclient "github.com/iansmith/go-github-client/client" + ghgists "github.com/iansmith/go-github-client/gists" ) func main() { diff --git a/examples/gh_get_gistslist/main.go b/examples/gh_get_gistslist/main.go index 186dbe1..3a66f6d 100644 --- a/examples/gh_get_gistslist/main.go +++ b/examples/gh_get_gistslist/main.go @@ -7,8 +7,8 @@ package main import ( "flag" "fmt" - ghclient "github.com/alcacoop/go-github-client/client" - ghgists "github.com/alcacoop/go-github-client/gists" + ghclient "github.com/iansmith/go-github-client/client" + ghgists "github.com/iansmith/go-github-client/gists" ) func main() { diff --git a/examples/gh_get_issueslist/main.go b/examples/gh_get_issueslist/main.go index 139fe16..8f0274c 100644 --- a/examples/gh_get_issueslist/main.go +++ b/examples/gh_get_issueslist/main.go @@ -8,8 +8,8 @@ import ( // "encoding/json" "flag" "fmt" - ghclient "github.com/alcacoop/go-github-client/client" - ghissues "github.com/alcacoop/go-github-client/issues" + ghclient "github.com/iansmith/go-github-client/client" + ghissues "github.com/iansmith/go-github-client/issues" ) func main() { diff --git a/issues/issue.go b/issues/issue.go index aaddd15..5266a58 100644 --- a/issues/issue.go +++ b/issues/issue.go @@ -8,7 +8,7 @@ import ( "bytes" "encoding/json" "errors" - ghclient "github.com/alcacoop/go-github-client/client" + ghclient "github.com/iansmith/go-github-client/client" "net/http" ) diff --git a/issues/issues.go b/issues/issues.go index a670068..3f7d37b 100644 --- a/issues/issues.go +++ b/issues/issues.go @@ -5,7 +5,7 @@ package issues import ( - ghclient "github.com/alcacoop/go-github-client/client" + ghclient "github.com/iansmith/go-github-client/client" ) // Issues is a simplified github issues api client diff --git a/issues/list.go b/issues/list.go index f8cfaa4..cb94663 100644 --- a/issues/list.go +++ b/issues/list.go @@ -8,7 +8,7 @@ import ( "bytes" "encoding/json" "errors" - ghclient "github.com/alcacoop/go-github-client/client" + ghclient "github.com/iansmith/go-github-client/client" "net/http" ) diff --git a/repos/repos.go b/repos/repos.go index a344f0d..37bda2b 100644 --- a/repos/repos.go +++ b/repos/repos.go @@ -5,8 +5,8 @@ package repos import ( - ghclient "github.com/alcacoop/go-github-client/client" - ghuser "github.com/alcacoop/go-github-client/users" + ghclient "github.com/iansmith/go-github-client/client" + ghuser "github.com/iansmith/go-github-client/users" "fmt" "net/http" ) diff --git a/users/users.go b/users/users.go index 4a36ab6..399f3ea 100644 --- a/users/users.go +++ b/users/users.go @@ -5,7 +5,7 @@ package users import ( - ghclient "github.com/alcacoop/go-github-client/client" + ghclient "github.com/iansmith/go-github-client/client" "net/http" )