| @@ -0,0 +1,20 @@ | |||
| Copyright (c) 2016 The Gitea Authors | |||
| Copyright (c) 2014 The Gogs Authors | |||
| Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| of this software and associated documentation files (the "Software"), to deal | |||
| in the Software without restriction, including without limitation the rights | |||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||
| copies of the Software, and to permit persons to whom the Software is | |||
| furnished to do so, subject to the following conditions: | |||
| The above copyright notice and this permission notice shall be included in | |||
| all copies or substantial portions of the Software. | |||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |||
| THE SOFTWARE. | |||
| @@ -0,0 +1,21 @@ | |||
| // Copyright 2015 The Gogs Authors. All rights reserved. | |||
| // Use of this source code is governed by a MIT-style | |||
| // license that can be found in the LICENSE file. | |||
| package gitea | |||
| import ( | |||
| "bytes" | |||
| "encoding/json" | |||
| "fmt" | |||
| ) | |||
| func (c *Client) AdminCreateOrg(user string, opt CreateOrgOption) (*Organization, error) { | |||
| body, err := json.Marshal(&opt) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| org := new(Organization) | |||
| return org, c.getParsedResponse("POST", fmt.Sprintf("/admin/users/%s/orgs", user), | |||
| jsonHeader, bytes.NewReader(body), org) | |||
| } | |||
| @@ -0,0 +1,21 @@ | |||
| // Copyright 2015 The Gogs Authors. All rights reserved. | |||
| // Use of this source code is governed by a MIT-style | |||
| // license that can be found in the LICENSE file. | |||
| package gitea | |||
| import ( | |||
| "bytes" | |||
| "encoding/json" | |||
| "fmt" | |||
| ) | |||
| func (c *Client) AdminCreateRepo(user string, opt CreateRepoOption) (*Repository, error) { | |||
| body, err := json.Marshal(&opt) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| repo := new(Repository) | |||
| return repo, c.getParsedResponse("POST", fmt.Sprintf("/admin/users/%s/repos", user), | |||
| jsonHeader, bytes.NewReader(body), repo) | |||
| } | |||
| @@ -0,0 +1,68 @@ | |||
| // Copyright 2015 The Gogs Authors. All rights reserved. | |||
| // Use of this source code is governed by a MIT-style | |||
| // license that can be found in the LICENSE file. | |||
| package gitea | |||
| import ( | |||
| "bytes" | |||
| "encoding/json" | |||
| "fmt" | |||
| ) | |||
| type CreateUserOption struct { | |||
| SourceID int64 `json:"source_id"` | |||
| LoginName string `json:"login_name"` | |||
| Username string `json:"username" binding:"Required;AlphaDashDot;MaxSize(35)"` | |||
| FullName string `json:"full_name" binding:"MaxSize(100)"` | |||
| Email string `json:"email" binding:"Required;Email;MaxSize(254)"` | |||
| Password string `json:"password" binding:"MaxSize(255)"` | |||
| SendNotify bool `json:"send_notify"` | |||
| } | |||
| func (c *Client) AdminCreateUser(opt CreateUserOption) (*User, error) { | |||
| body, err := json.Marshal(&opt) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| user := new(User) | |||
| return user, c.getParsedResponse("POST", "/admin/users", jsonHeader, bytes.NewReader(body), user) | |||
| } | |||
| type EditUserOption struct { | |||
| SourceID int64 `json:"source_id"` | |||
| LoginName string `json:"login_name"` | |||
| FullName string `json:"full_name" binding:"MaxSize(100)"` | |||
| Email string `json:"email" binding:"Required;Email;MaxSize(254)"` | |||
| Password string `json:"password" binding:"MaxSize(255)"` | |||
| Website string `json:"website" binding:"MaxSize(50)"` | |||
| Location string `json:"location" binding:"MaxSize(50)"` | |||
| Active *bool `json:"active"` | |||
| Admin *bool `json:"admin"` | |||
| AllowGitHook *bool `json:"allow_git_hook"` | |||
| AllowImportLocal *bool `json:"allow_import_local"` | |||
| MaxRepoCreation *int `json:"max_repo_creation"` | |||
| } | |||
| func (c *Client) AdminEditUser(user string, opt EditUserOption) error { | |||
| body, err := json.Marshal(&opt) | |||
| if err != nil { | |||
| return err | |||
| } | |||
| _, err = c.getResponse("PATCH", fmt.Sprintf("/admin/users/%s", user), jsonHeader, bytes.NewReader(body)) | |||
| return err | |||
| } | |||
| func (c *Client) AdminDeleteUser(user string) error { | |||
| _, err := c.getResponse("DELETE", fmt.Sprintf("/admin/users/%s", user), nil, nil) | |||
| return err | |||
| } | |||
| func (c *Client) AdminCreateUserPublicKey(user string, opt CreateKeyOption) (*PublicKey, error) { | |||
| body, err := json.Marshal(&opt) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| key := new(PublicKey) | |||
| return key, c.getParsedResponse("POST", fmt.Sprintf("/admin/users/%s/keys", user), jsonHeader, bytes.NewReader(body), key) | |||
| } | |||
| @@ -0,0 +1,90 @@ | |||
| // Copyright 2014 The Gogs Authors. All rights reserved. | |||
| // Use of this source code is governed by a MIT-style | |||
| // license that can be found in the LICENSE file. | |||
| package gitea | |||
| import ( | |||
| "encoding/json" | |||
| "errors" | |||
| "io" | |||
| "io/ioutil" | |||
| "net/http" | |||
| "strings" | |||
| ) | |||
| func Version() string { | |||
| return "0.12.3" | |||
| } | |||
| // Client represents a Gogs API client. | |||
| type Client struct { | |||
| url string | |||
| accessToken string | |||
| client *http.Client | |||
| } | |||
| // NewClient initializes and returns a API client. | |||
| func NewClient(url, token string) *Client { | |||
| return &Client{ | |||
| url: strings.TrimSuffix(url, "/"), | |||
| accessToken: token, | |||
| client: &http.Client{}, | |||
| } | |||
| } | |||
| // SetHTTPClient replaces default http.Client with user given one. | |||
| func (c *Client) SetHTTPClient(client *http.Client) { | |||
| c.client = client | |||
| } | |||
| func (c *Client) doRequest(method, path string, header http.Header, body io.Reader) (*http.Response, error) { | |||
| req, err := http.NewRequest(method, c.url+"/api/v1"+path, body) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| req.Header.Set("Authorization", "token "+c.accessToken) | |||
| for k, v := range header { | |||
| req.Header[k] = v | |||
| } | |||
| return c.client.Do(req) | |||
| } | |||
| func (c *Client) getResponse(method, path string, header http.Header, body io.Reader) ([]byte, error) { | |||
| resp, err := c.doRequest(method, path, header, body) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| defer resp.Body.Close() | |||
| data, err := ioutil.ReadAll(resp.Body) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| switch resp.StatusCode { | |||
| case 403: | |||
| return nil, errors.New("403 Forbidden") | |||
| case 404: | |||
| return nil, errors.New("404 Not Found") | |||
| } | |||
| if resp.StatusCode/100 != 2 { | |||
| errMap := make(map[string]interface{}) | |||
| if err = json.Unmarshal(data, &errMap); err != nil { | |||
| return nil, err | |||
| } | |||
| return nil, errors.New(errMap["message"].(string)) | |||
| } | |||
| return data, nil | |||
| } | |||
| func (c *Client) getParsedResponse(method, path string, header http.Header, body io.Reader, obj interface{}) error { | |||
| data, err := c.getResponse(method, path, header, body) | |||
| if err != nil { | |||
| return err | |||
| } | |||
| return json.Unmarshal(data, obj) | |||
| } | |||
| @@ -0,0 +1,92 @@ | |||
| // Copyright 2016 The Gogs Authors. All rights reserved. | |||
| // Use of this source code is governed by a MIT-style | |||
| // license that can be found in the LICENSE file. | |||
| package gitea | |||
| import ( | |||
| "bytes" | |||
| "encoding/json" | |||
| "fmt" | |||
| "time" | |||
| ) | |||
| type StateType string | |||
| const ( | |||
| STATE_OPEN StateType = "open" | |||
| STATE_CLOSED StateType = "closed" | |||
| ) | |||
| type PullRequestMeta struct { | |||
| HasMerged bool `json:"merged"` | |||
| Merged *time.Time `json:"merged_at"` | |||
| } | |||
| type Issue struct { | |||
| ID int64 `json:"id"` | |||
| Index int64 `json:"number"` | |||
| Poster *User `json:"user"` | |||
| Title string `json:"title"` | |||
| Body string `json:"body"` | |||
| Labels []*Label `json:"labels"` | |||
| Milestone *Milestone `json:"milestone"` | |||
| Assignee *User `json:"assignee"` | |||
| State StateType `json:"state"` | |||
| Comments int `json:"comments"` | |||
| Created time.Time `json:"created_at"` | |||
| Updated time.Time `json:"updated_at"` | |||
| PullRequest *PullRequestMeta `json:"pull_request"` | |||
| } | |||
| type ListIssueOption struct { | |||
| Page int | |||
| } | |||
| func (c *Client) ListRepoIssues(owner, repo string, opt ListIssueOption) ([]*Issue, error) { | |||
| issues := make([]*Issue, 0, 10) | |||
| return issues, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues?page=%d", owner, repo, opt.Page), nil, nil, &issues) | |||
| } | |||
| func (c *Client) GetIssue(owner, repo string, index int64) (*Issue, error) { | |||
| issue := new(Issue) | |||
| return issue, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/%d", owner, repo, index), nil, nil, issue) | |||
| } | |||
| type CreateIssueOption struct { | |||
| Title string `json:"title" binding:"Required"` | |||
| Body string `json:"body"` | |||
| Assignee string `json:"assignee"` | |||
| Milestone int64 `json:"milestone"` | |||
| Labels []int64 `json:"labels"` | |||
| Closed bool `json:"closed"` | |||
| } | |||
| func (c *Client) CreateIssue(owner, repo string, opt CreateIssueOption) (*Issue, error) { | |||
| body, err := json.Marshal(&opt) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| issue := new(Issue) | |||
| return issue, c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/issues", owner, repo), | |||
| jsonHeader, bytes.NewReader(body), issue) | |||
| } | |||
| type EditIssueOption struct { | |||
| Title string `json:"title"` | |||
| Body *string `json:"body"` | |||
| Assignee *string `json:"assignee"` | |||
| Milestone *int64 `json:"milestone"` | |||
| State *string `json:"state"` | |||
| } | |||
| func (c *Client) EditIssue(owner, repo string, index int64, opt EditIssueOption) (*Issue, error) { | |||
| body, err := json.Marshal(&opt) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| issue := new(Issue) | |||
| return issue, c.getParsedResponse("PATCH", fmt.Sprintf("/repos/%s/%s/issues/%d", owner, repo, index), | |||
| jsonHeader, bytes.NewReader(body), issue) | |||
| } | |||
| @@ -0,0 +1,57 @@ | |||
| // Copyright 2016 The Gogs Authors. All rights reserved. | |||
| // Use of this source code is governed by a MIT-style | |||
| // license that can be found in the LICENSE file. | |||
| package gitea | |||
| import ( | |||
| "bytes" | |||
| "encoding/json" | |||
| "fmt" | |||
| "time" | |||
| ) | |||
| // Comment represents a comment in commit and issue page. | |||
| type Comment struct { | |||
| ID int64 `json:"id"` | |||
| Poster *User `json:"user"` | |||
| Body string `json:"body"` | |||
| Created time.Time `json:"created_at"` | |||
| Updated time.Time `json:"updated_at"` | |||
| } | |||
| // ListIssueComments list comments on an issue. | |||
| func (c *Client) ListIssueComments(owner, repo string, index int64) ([]*Comment, error) { | |||
| comments := make([]*Comment, 0, 10) | |||
| return comments, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/%d/comments", owner, repo, index), nil, nil, &comments) | |||
| } | |||
| // CreateIssueCommentOption is option when creating an issue comment. | |||
| type CreateIssueCommentOption struct { | |||
| Body string `json:"body" binding:"Required"` | |||
| } | |||
| // CreateIssueComment create comment on an issue. | |||
| func (c *Client) CreateIssueComment(owner, repo string, index int64, opt CreateIssueCommentOption) (*Comment, error) { | |||
| body, err := json.Marshal(&opt) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| comment := new(Comment) | |||
| return comment, c.getParsedResponse("POST", fmt.Sprintf("/repos/:%s/:%s/issues/%d/comments", owner, repo, index), jsonHeader, bytes.NewReader(body), comment) | |||
| } | |||
| // EditIssueCommentOption is option when editing an issue comment. | |||
| type EditIssueCommentOption struct { | |||
| Body string `json:"body" binding:"Required"` | |||
| } | |||
| // EditIssueComment edits an issue comment. | |||
| func (c *Client) EditIssueComment(owner, repo string, index, commentID int64, opt EditIssueCommentOption) (*Comment, error) { | |||
| body, err := json.Marshal(&opt) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| comment := new(Comment) | |||
| return comment, c.getParsedResponse("PATCH", fmt.Sprintf("/repos/:%s/:%s/issues/%d/comments/%d", owner, repo, index, commentID), jsonHeader, bytes.NewReader(body), comment) | |||
| } | |||
| @@ -0,0 +1,98 @@ | |||
| // Copyright 2016 The Gogs Authors. All rights reserved. | |||
| // Use of this source code is governed by a MIT-style | |||
| // license that can be found in the LICENSE file. | |||
| package gitea | |||
| import ( | |||
| "bytes" | |||
| "encoding/json" | |||
| "fmt" | |||
| ) | |||
| type Label struct { | |||
| ID int64 `json:"id"` | |||
| Name string `json:"name"` | |||
| Color string `json:"color"` | |||
| } | |||
| func (c *Client) ListRepoLabels(owner, repo string) ([]*Label, error) { | |||
| labels := make([]*Label, 0, 10) | |||
| return labels, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/labels", owner, repo), nil, nil, &labels) | |||
| } | |||
| func (c *Client) GetRepoLabel(owner, repo string, id int64) (*Label, error) { | |||
| label := new(Label) | |||
| return label, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/labels/%d", owner, repo, id), nil, nil, label) | |||
| } | |||
| type CreateLabelOption struct { | |||
| Name string `json:"name" binding:"Required"` | |||
| Color string `json:"color" binding:"Required;Size(7)"` | |||
| } | |||
| func (c *Client) CreateLabel(owner, repo string, opt CreateLabelOption) (*Label, error) { | |||
| body, err := json.Marshal(&opt) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| label := new(Label) | |||
| return label, c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/labels", owner, repo), | |||
| jsonHeader, bytes.NewReader(body), label) | |||
| } | |||
| type EditLabelOption struct { | |||
| Name *string `json:"name"` | |||
| Color *string `json:"color"` | |||
| } | |||
| func (c *Client) EditLabel(owner, repo string, id int64, opt EditLabelOption) (*Label, error) { | |||
| body, err := json.Marshal(&opt) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| label := new(Label) | |||
| return label, c.getParsedResponse("PATCH", fmt.Sprintf("/repos/%s/%s/labels/%d", owner, repo, id), jsonHeader, bytes.NewReader(body), label) | |||
| } | |||
| func (c *Client) DeleteLabel(owner, repo string, id int64) error { | |||
| _, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/labels/%d", owner, repo, id), nil, nil) | |||
| return err | |||
| } | |||
| type IssueLabelsOption struct { | |||
| Labels []int64 `json:"labels"` | |||
| } | |||
| func (c *Client) GetIssueLabels(owner, repo string, index int64) ([]*Label, error) { | |||
| labels := make([]*Label, 0, 5) | |||
| return labels, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/issues/%d/labels", owner, repo, index), nil, nil, &labels) | |||
| } | |||
| func (c *Client) AddIssueLabels(owner, repo string, index int64, opt IssueLabelsOption) ([]*Label, error) { | |||
| body, err := json.Marshal(&opt) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| labels := make([]*Label, 0) | |||
| return labels, c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/issues/%d/labels", owner, repo, index), jsonHeader, bytes.NewReader(body), &labels) | |||
| } | |||
| func (c *Client) ReplaceIssueLabels(owner, repo string, index int64, opt IssueLabelsOption) ([]*Label, error) { | |||
| body, err := json.Marshal(&opt) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| labels := make([]*Label, 0) | |||
| return labels, c.getParsedResponse("PUT", fmt.Sprintf("/repos/%s/%s/issues/%d/labels", owner, repo, index), jsonHeader, bytes.NewReader(body), &labels) | |||
| } | |||
| func (c *Client) DeleteIssueLabel(owner, repo string, index, label int64) error { | |||
| _, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/labels/%d", owner, repo, index, label), nil, nil) | |||
| return err | |||
| } | |||
| func (c *Client) ClearIssueLabels(owner, repo string, index int64) error { | |||
| _, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/issues/%d/labels", owner, repo, index), nil, nil) | |||
| return err | |||
| } | |||
| @@ -0,0 +1,69 @@ | |||
| // Copyright 2016 The Gogs Authors. All rights reserved. | |||
| // Use of this source code is governed by a MIT-style | |||
| // license that can be found in the LICENSE file. | |||
| package gitea | |||
| import ( | |||
| "bytes" | |||
| "encoding/json" | |||
| "fmt" | |||
| "time" | |||
| ) | |||
| type Milestone struct { | |||
| ID int64 `json:"id"` | |||
| Title string `json:"title"` | |||
| Description string `json:"description"` | |||
| State StateType `json:"state"` | |||
| OpenIssues int `json:"open_issues"` | |||
| ClosedIssues int `json:"closed_issues"` | |||
| Closed *time.Time `json:"closed_at"` | |||
| Deadline *time.Time `json:"due_on"` | |||
| } | |||
| func (c *Client) ListRepoMilestones(owner, repo string) ([]*Milestone, error) { | |||
| milestones := make([]*Milestone, 0, 10) | |||
| return milestones, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/milestones", owner, repo), nil, nil, &milestones) | |||
| } | |||
| func (c *Client) GetMilestone(owner, repo string, id int64) (*Milestone, error) { | |||
| milestone := new(Milestone) | |||
| return milestone, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/milestones/%d", owner, repo, id), nil, nil, milestone) | |||
| } | |||
| type CreateMilestoneOption struct { | |||
| Title string `json:"title"` | |||
| Description string `json:"description"` | |||
| Deadline *time.Time `json:"due_on"` | |||
| } | |||
| func (c *Client) CreateMilestone(owner, repo string, opt CreateMilestoneOption) (*Milestone, error) { | |||
| body, err := json.Marshal(&opt) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| milestone := new(Milestone) | |||
| return milestone, c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/milestones", owner, repo), jsonHeader, bytes.NewReader(body), milestone) | |||
| } | |||
| type EditMilestoneOption struct { | |||
| Title string `json:"title"` | |||
| Description *string `json:"description"` | |||
| State *string `json:"state"` | |||
| Deadline *time.Time `json:"due_on"` | |||
| } | |||
| func (c *Client) EditMilestone(owner, repo string, id int64, opt EditMilestoneOption) (*Milestone, error) { | |||
| body, err := json.Marshal(&opt) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| milestone := new(Milestone) | |||
| return milestone, c.getParsedResponse("PATCH", fmt.Sprintf("/repos/%s/%s/milestones/%d", owner, repo, id), jsonHeader, bytes.NewReader(body), milestone) | |||
| } | |||
| func (c *Client) DeleteMilestone(owner, repo string, id int64) error { | |||
| _, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/milestones/%d", owner, repo, id), nil, nil) | |||
| return err | |||
| } | |||
| @@ -0,0 +1,11 @@ | |||
| // Copyright 2015 The Gogs Authors. All rights reserved. | |||
| // Use of this source code is governed by a MIT-style | |||
| // license that can be found in the LICENSE file. | |||
| package gitea | |||
| type MarkdownOption struct { | |||
| Text string | |||
| Mode string | |||
| Context string | |||
| } | |||
| @@ -0,0 +1,60 @@ | |||
| // Copyright 2015 The Gogs Authors. All rights reserved. | |||
| // Use of this source code is governed by a MIT-style | |||
| // license that can be found in the LICENSE file. | |||
| package gitea | |||
| import ( | |||
| "bytes" | |||
| "encoding/json" | |||
| "fmt" | |||
| ) | |||
| type Organization struct { | |||
| ID int64 `json:"id"` | |||
| UserName string `json:"username"` | |||
| FullName string `json:"full_name"` | |||
| AvatarUrl string `json:"avatar_url"` | |||
| Description string `json:"description"` | |||
| Website string `json:"website"` | |||
| Location string `json:"location"` | |||
| } | |||
| func (c *Client) ListMyOrgs() ([]*Organization, error) { | |||
| orgs := make([]*Organization, 0, 5) | |||
| return orgs, c.getParsedResponse("GET", "/user/orgs", nil, nil, &orgs) | |||
| } | |||
| func (c *Client) ListUserOrgs(user string) ([]*Organization, error) { | |||
| orgs := make([]*Organization, 0, 5) | |||
| return orgs, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/orgs", user), nil, nil, &orgs) | |||
| } | |||
| func (c *Client) GetOrg(orgname string) (*Organization, error) { | |||
| org := new(Organization) | |||
| return org, c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s", orgname), nil, nil, org) | |||
| } | |||
| type CreateOrgOption struct { | |||
| UserName string `json:"username" binding:"Required"` | |||
| FullName string `json:"full_name"` | |||
| Description string `json:"description"` | |||
| Website string `json:"website"` | |||
| Location string `json:"location"` | |||
| } | |||
| type EditOrgOption struct { | |||
| FullName string `json:"full_name"` | |||
| Description string `json:"description"` | |||
| Website string `json:"website"` | |||
| Location string `json:"location"` | |||
| } | |||
| func (c *Client) EditOrg(orgname string, opt EditOrgOption) error { | |||
| body, err := json.Marshal(&opt) | |||
| if err != nil { | |||
| return err | |||
| } | |||
| _, err = c.getResponse("PATCH", fmt.Sprintf("/orgs/%s", orgname), jsonHeader, bytes.NewReader(body)) | |||
| return err | |||
| } | |||
| @@ -0,0 +1,24 @@ | |||
| // Copyright 2016 The Gogs Authors. All rights reserved. | |||
| // Use of this source code is governed by a MIT-style | |||
| // license that can be found in the LICENSE file. | |||
| package gitea | |||
| import ( | |||
| "bytes" | |||
| "encoding/json" | |||
| "fmt" | |||
| ) | |||
| type AddOrgMembershipOption struct { | |||
| Role string `json:"role" binding:"Required"` | |||
| } | |||
| func (c *Client) AddOrgMembership(org, user string, opt AddOrgMembershipOption) error { | |||
| body, err := json.Marshal(&opt) | |||
| if err != nil { | |||
| return err | |||
| } | |||
| _, err = c.getResponse("PUT", fmt.Sprintf("/orgs/%s/membership/%s", org, user), jsonHeader, bytes.NewReader(body)) | |||
| return err | |||
| } | |||
| @@ -0,0 +1,18 @@ | |||
| // Copyright 2016 The Gogs Authors. All rights reserved. | |||
| // Use of this source code is governed by a MIT-style | |||
| // license that can be found in the LICENSE file. | |||
| package gitea | |||
| type Team struct { | |||
| ID int64 `json:"id"` | |||
| Name string `json:"name"` | |||
| Description string `json:"description"` | |||
| Permission string `json:"permission"` | |||
| } | |||
| type CreateTeamOption struct { | |||
| Name string `json:"name" binding:"Required;AlphaDashDot;MaxSize(30)"` | |||
| Description string `json:"description" binding:"MaxSize(255)"` | |||
| Permission string `json:"permission"` | |||
| } | |||
| @@ -0,0 +1,37 @@ | |||
| // Copyright 2016 The Gogs Authors. All rights reserved. | |||
| // Use of this source code is governed by a MIT-style | |||
| // license that can be found in the LICENSE file. | |||
| package gitea | |||
| import ( | |||
| "time" | |||
| ) | |||
| // PullRequest represents a pull reqesut API object. | |||
| type PullRequest struct { | |||
| // Copied from issue.go | |||
| ID int64 `json:"id"` | |||
| Index int64 `json:"number"` | |||
| Poster *User `json:"user"` | |||
| Title string `json:"title"` | |||
| Body string `json:"body"` | |||
| Labels []*Label `json:"labels"` | |||
| Milestone *Milestone `json:"milestone"` | |||
| Assignee *User `json:"assignee"` | |||
| State StateType `json:"state"` | |||
| Comments int `json:"comments"` | |||
| HeadBranch string `json:"head_branch"` | |||
| HeadRepo *Repository `json:"head_repo"` | |||
| BaseBranch string `json:"base_branch"` | |||
| BaseRepo *Repository `json:"base_repo"` | |||
| HTMLURL string `json:"html_url"` | |||
| Mergeable *bool `json:"mergeable"` | |||
| HasMerged bool `json:"merged"` | |||
| Merged *time.Time `json:"merged_at"` | |||
| MergedCommitID *string `json:"merge_commit_sha"` | |||
| MergedBy *User `json:"merged_by"` | |||
| } | |||
| @@ -0,0 +1,125 @@ | |||
| // Copyright 2014 The Gogs Authors. All rights reserved. | |||
| // Use of this source code is governed by a MIT-style | |||
| // license that can be found in the LICENSE file. | |||
| package gitea | |||
| import ( | |||
| "bytes" | |||
| "encoding/json" | |||
| "fmt" | |||
| "time" | |||
| ) | |||
| // Permission represents a API permission. | |||
| type Permission struct { | |||
| Admin bool `json:"admin"` | |||
| Push bool `json:"push"` | |||
| Pull bool `json:"pull"` | |||
| } | |||
| // Repository represents a API repository. | |||
| type Repository struct { | |||
| ID int64 `json:"id"` | |||
| Owner *User `json:"owner"` | |||
| Name string `json:"name"` | |||
| FullName string `json:"full_name"` | |||
| Description string `json:"description"` | |||
| Private bool `json:"private"` | |||
| Fork bool `json:"fork"` | |||
| HTMLURL string `json:"html_url"` | |||
| SSHURL string `json:"ssh_url"` | |||
| CloneURL string `json:"clone_url"` | |||
| Website string `json:"website"` | |||
| Stars int `json:"stars_count"` | |||
| Forks int `json:"forks_count"` | |||
| Watchers int `json:"watchers_count"` | |||
| OpenIssues int `json:"open_issues_count"` | |||
| DefaultBranch string `json:"default_branch"` | |||
| Created time.Time `json:"created_at"` | |||
| Updated time.Time `json:"updated_at"` | |||
| Permissions *Permission `json:"permissions,omitempty"` | |||
| } | |||
| // ListMyRepos lists all repositories for the authenticated user that has access to. | |||
| func (c *Client) ListMyRepos() ([]*Repository, error) { | |||
| repos := make([]*Repository, 0, 10) | |||
| return repos, c.getParsedResponse("GET", "/user/repos", nil, nil, &repos) | |||
| } | |||
| func (c *Client) ListUserRepos(user string) ([]*Repository, error) { | |||
| repos := make([]*Repository, 0, 10) | |||
| return repos, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/repos", user), nil, nil, &repos) | |||
| } | |||
| func (c *Client) ListOrgRepos(org string) ([]*Repository, error) { | |||
| repos := make([]*Repository, 0, 10) | |||
| return repos, c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s/repos", org), nil, nil, &repos) | |||
| } | |||
| type CreateRepoOption struct { | |||
| Name string `json:"name" binding:"Required;AlphaDashDot;MaxSize(100)"` | |||
| Description string `json:"description" binding:"MaxSize(255)"` | |||
| Private bool `json:"private"` | |||
| AutoInit bool `json:"auto_init"` | |||
| Gitignores string `json:"gitignores"` | |||
| License string `json:"license"` | |||
| Readme string `json:"readme"` | |||
| } | |||
| // CreateRepo creates a repository for authenticated user. | |||
| func (c *Client) CreateRepo(opt CreateRepoOption) (*Repository, error) { | |||
| body, err := json.Marshal(&opt) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| repo := new(Repository) | |||
| return repo, c.getParsedResponse("POST", "/user/repos", jsonHeader, bytes.NewReader(body), repo) | |||
| } | |||
| // CreateOrgRepo creates an organization repository for authenticated user. | |||
| func (c *Client) CreateOrgRepo(org string, opt CreateRepoOption) (*Repository, error) { | |||
| body, err := json.Marshal(&opt) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| repo := new(Repository) | |||
| return repo, c.getParsedResponse("POST", fmt.Sprintf("/org/%s/repos", org), jsonHeader, bytes.NewReader(body), repo) | |||
| } | |||
| // GetRepo returns information of a repository of given owner. | |||
| func (c *Client) GetRepo(owner, reponame string) (*Repository, error) { | |||
| repo := new(Repository) | |||
| return repo, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s", owner, reponame), nil, nil, repo) | |||
| } | |||
| // DeleteRepo deletes a repository of user or organization. | |||
| func (c *Client) DeleteRepo(owner, repo string) error { | |||
| _, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s", owner, repo), nil, nil) | |||
| return err | |||
| } | |||
| type MigrateRepoOption struct { | |||
| CloneAddr string `json:"clone_addr" binding:"Required"` | |||
| AuthUsername string `json:"auth_username"` | |||
| AuthPassword string `json:"auth_password"` | |||
| UID int `json:"uid" binding:"Required"` | |||
| RepoName string `json:"repo_name" binding:"Required"` | |||
| Mirror bool `json:"mirror"` | |||
| Private bool `json:"private"` | |||
| Description string `json:"description"` | |||
| } | |||
| // MigrateRepo migrates a repository from other Git hosting sources for the | |||
| // authenticated user. | |||
| // | |||
| // To migrate a repository for a organization, the authenticated user must be a | |||
| // owner of the specified organization. | |||
| func (c *Client) MigrateRepo(opt MigrateRepoOption) (*Repository, error) { | |||
| body, err := json.Marshal(&opt) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| repo := new(Repository) | |||
| return repo, c.getParsedResponse("POST", "/repos/migrate", jsonHeader, bytes.NewReader(body), repo) | |||
| } | |||
| @@ -0,0 +1,25 @@ | |||
| // Copyright 2016 The Gogs Authors. All rights reserved. | |||
| // Use of this source code is governed by a MIT-style | |||
| // license that can be found in the LICENSE file. | |||
| package gitea | |||
| import ( | |||
| "fmt" | |||
| ) | |||
| // Branch represents a repository branch. | |||
| type Branch struct { | |||
| Name string `json:"name"` | |||
| Commit *PayloadCommit `json:"commit"` | |||
| } | |||
| func (c *Client) ListRepoBranches(user, repo string) ([]*Branch, error) { | |||
| branches := make([]*Branch, 0, 10) | |||
| return branches, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/branches", user, repo), nil, nil, &branches) | |||
| } | |||
| func (c *Client) GetRepoBranch(user, repo, branch string) (*Branch, error) { | |||
| b := new(Branch) | |||
| return b, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/branches/%s", user, repo, branch), nil, nil, &b) | |||
| } | |||
| @@ -0,0 +1,24 @@ | |||
| // Copyright 2016 The Gogs Authors. All rights reserved. | |||
| // Use of this source code is governed by a MIT-style | |||
| // license that can be found in the LICENSE file. | |||
| package gitea | |||
| import ( | |||
| "bytes" | |||
| "encoding/json" | |||
| "fmt" | |||
| ) | |||
| type AddCollaboratorOption struct { | |||
| Permission *string `json:"permission"` | |||
| } | |||
| func (c *Client) AddCollaborator(user, repo, collaborator string, opt AddCollaboratorOption) error { | |||
| body, err := json.Marshal(&opt) | |||
| if err != nil { | |||
| return err | |||
| } | |||
| _, err = c.getResponse("PUT", fmt.Sprintf("/repos/%s/%s/collaborators/%s", user, repo, collaborator), nil, bytes.NewReader(body)) | |||
| return err | |||
| } | |||
| @@ -0,0 +1,15 @@ | |||
| // Copyright 2014 The Gogs Authors. All rights reserved. | |||
| // Use of this source code is governed by a MIT-style | |||
| // license that can be found in the LICENSE file. | |||
| package gitea | |||
| import ( | |||
| "fmt" | |||
| ) | |||
| // GetFile downloads a file of repository, ref can be branch/tag/commit. | |||
| // e.g.: ref -> master, tree -> macaron.go(no leading slash) | |||
| func (c *Client) GetFile(user, repo, ref, tree string) ([]byte, error) { | |||
| return c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/raw/%s/%s", user, repo, ref, tree), nil, nil) | |||
| } | |||
| @@ -0,0 +1,245 @@ | |||
| // Copyright 2014 The Gogs Authors. All rights reserved. | |||
| // Use of this source code is governed by a MIT-style | |||
| // license that can be found in the LICENSE file. | |||
| package gitea | |||
| import ( | |||
| "bytes" | |||
| "encoding/json" | |||
| "errors" | |||
| "fmt" | |||
| "strings" | |||
| "time" | |||
| ) | |||
| var ( | |||
| ErrInvalidReceiveHook = errors.New("Invalid JSON payload received over webhook") | |||
| ) | |||
| type Hook struct { | |||
| ID int64 `json:"id"` | |||
| Type string `json:"type"` | |||
| URL string `json:"-"` | |||
| Config map[string]string `json:"config"` | |||
| Events []string `json:"events"` | |||
| Active bool `json:"active"` | |||
| Updated time.Time `json:"updated_at"` | |||
| Created time.Time `json:"created_at"` | |||
| } | |||
| func (c *Client) ListRepoHooks(user, repo string) ([]*Hook, error) { | |||
| hooks := make([]*Hook, 0, 10) | |||
| return hooks, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/hooks", user, repo), nil, nil, &hooks) | |||
| } | |||
| type CreateHookOption struct { | |||
| Type string `json:"type" binding:"Required"` | |||
| Config map[string]string `json:"config" binding:"Required"` | |||
| Events []string `json:"events"` | |||
| Active bool `json:"active"` | |||
| } | |||
| func (c *Client) CreateRepoHook(user, repo string, opt CreateHookOption) (*Hook, error) { | |||
| body, err := json.Marshal(&opt) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| h := new(Hook) | |||
| return h, c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/hooks", user, repo), jsonHeader, bytes.NewReader(body), h) | |||
| } | |||
| type EditHookOption struct { | |||
| Config map[string]string `json:"config"` | |||
| Events []string `json:"events"` | |||
| Active *bool `json:"active"` | |||
| } | |||
| func (c *Client) EditRepoHook(user, repo string, id int64, opt EditHookOption) error { | |||
| body, err := json.Marshal(&opt) | |||
| if err != nil { | |||
| return err | |||
| } | |||
| _, err = c.getResponse("PATCH", fmt.Sprintf("/repos/%s/%s/hooks/%d", user, repo, id), jsonHeader, bytes.NewReader(body)) | |||
| return err | |||
| } | |||
| func (c *Client) DeleteRepoHook(user, repo string, id int64) error { | |||
| _, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/hooks/%d", user, repo, id), nil, nil) | |||
| return err | |||
| } | |||
| type Payloader interface { | |||
| SetSecret(string) | |||
| JSONPayload() ([]byte, error) | |||
| } | |||
| type PayloadUser struct { | |||
| Name string `json:"name"` | |||
| Email string `json:"email"` | |||
| UserName string `json:"username"` | |||
| } | |||
| // FIXME: consider use same format as API when commits API are added. | |||
| type PayloadCommit struct { | |||
| ID string `json:"id"` | |||
| Message string `json:"message"` | |||
| URL string `json:"url"` | |||
| Author *PayloadUser `json:"author"` | |||
| Committer *PayloadUser `json:"committer"` | |||
| Timestamp time.Time `json:"timestamp"` | |||
| } | |||
| var ( | |||
| _ Payloader = &CreatePayload{} | |||
| _ Payloader = &PushPayload{} | |||
| _ Payloader = &PullRequestPayload{} | |||
| ) | |||
| // _________ __ | |||
| // \_ ___ \_______ ____ _____ _/ |_ ____ | |||
| // / \ \/\_ __ \_/ __ \\__ \\ __\/ __ \ | |||
| // \ \____| | \/\ ___/ / __ \| | \ ___/ | |||
| // \______ /|__| \___ >____ /__| \___ > | |||
| // \/ \/ \/ \/ | |||
| type CreatePayload struct { | |||
| Secret string `json:"secret"` | |||
| Ref string `json:"ref"` | |||
| RefType string `json:"ref_type"` | |||
| Repo *Repository `json:"repository"` | |||
| Sender *User `json:"sender"` | |||
| } | |||
| func (p *CreatePayload) SetSecret(secret string) { | |||
| p.Secret = secret | |||
| } | |||
| func (p *CreatePayload) JSONPayload() ([]byte, error) { | |||
| return json.MarshalIndent(p, "", " ") | |||
| } | |||
| // ParseCreateHook parses create event hook content. | |||
| func ParseCreateHook(raw []byte) (*CreatePayload, error) { | |||
| hook := new(CreatePayload) | |||
| if err := json.Unmarshal(raw, hook); err != nil { | |||
| return nil, err | |||
| } | |||
| // it is possible the JSON was parsed, however, | |||
| // was not from Gogs (maybe was from Bitbucket) | |||
| // So we'll check to be sure certain key fields | |||
| // were populated | |||
| switch { | |||
| case hook.Repo == nil: | |||
| return nil, ErrInvalidReceiveHook | |||
| case len(hook.Ref) == 0: | |||
| return nil, ErrInvalidReceiveHook | |||
| } | |||
| return hook, nil | |||
| } | |||
| // __________ .__ | |||
| // \______ \__ __ _____| |__ | |||
| // | ___/ | \/ ___/ | \ | |||
| // | | | | /\___ \| Y \ | |||
| // |____| |____//____ >___| / | |||
| // \/ \/ | |||
| // PushPayload represents a payload information of push event. | |||
| type PushPayload struct { | |||
| Secret string `json:"secret"` | |||
| Ref string `json:"ref"` | |||
| Before string `json:"before"` | |||
| After string `json:"after"` | |||
| CompareURL string `json:"compare_url"` | |||
| Commits []*PayloadCommit `json:"commits"` | |||
| Repo *Repository `json:"repository"` | |||
| Pusher *User `json:"pusher"` | |||
| Sender *User `json:"sender"` | |||
| } | |||
| func (p *PushPayload) SetSecret(secret string) { | |||
| p.Secret = secret | |||
| } | |||
| func (p *PushPayload) JSONPayload() ([]byte, error) { | |||
| return json.MarshalIndent(p, "", " ") | |||
| } | |||
| // ParsePushHook parses push event hook content. | |||
| func ParsePushHook(raw []byte) (*PushPayload, error) { | |||
| hook := new(PushPayload) | |||
| if err := json.Unmarshal(raw, hook); err != nil { | |||
| return nil, err | |||
| } | |||
| switch { | |||
| case hook.Repo == nil: | |||
| return nil, ErrInvalidReceiveHook | |||
| case len(hook.Ref) == 0: | |||
| return nil, ErrInvalidReceiveHook | |||
| } | |||
| return hook, nil | |||
| } | |||
| // Branch returns branch name from a payload | |||
| func (p *PushPayload) Branch() string { | |||
| return strings.Replace(p.Ref, "refs/heads/", "", -1) | |||
| } | |||
| // .___ | |||
| // | | ______ ________ __ ____ | |||
| // | |/ ___// ___/ | \_/ __ \ | |||
| // | |\___ \ \___ \| | /\ ___/ | |||
| // |___/____ >____ >____/ \___ > | |||
| // \/ \/ \/ | |||
| type HookIssueAction string | |||
| const ( | |||
| HOOK_ISSUE_OPENED HookIssueAction = "opened" | |||
| HOOK_ISSUE_CLOSED HookIssueAction = "closed" | |||
| HOOK_ISSUE_REOPENED HookIssueAction = "reopened" | |||
| HOOK_ISSUE_EDITED HookIssueAction = "edited" | |||
| HOOK_ISSUE_ASSIGNED HookIssueAction = "assigned" | |||
| HOOK_ISSUE_UNASSIGNED HookIssueAction = "unassigned" | |||
| HOOK_ISSUE_LABEL_UPDATED HookIssueAction = "label_updated" | |||
| HOOK_ISSUE_LABEL_CLEARED HookIssueAction = "label_cleared" | |||
| HOOK_ISSUE_SYNCHRONIZED HookIssueAction = "synchronized" | |||
| ) | |||
| type ChangesFromPayload struct { | |||
| From string `json:"from"` | |||
| } | |||
| type ChangesPayload struct { | |||
| Title *ChangesFromPayload `json:"title,omitempty"` | |||
| Body *ChangesFromPayload `json:"body,omitempty"` | |||
| } | |||
| // __________ .__ .__ __________ __ | |||
| // \______ \__ __| | | | \______ \ ____ ________ __ ____ _______/ |_ | |||
| // | ___/ | \ | | | | _// __ \/ ____/ | \_/ __ \ / ___/\ __\ | |||
| // | | | | / |_| |__ | | \ ___< <_| | | /\ ___/ \___ \ | | | |||
| // |____| |____/|____/____/ |____|_ /\___ >__ |____/ \___ >____ > |__| | |||
| // \/ \/ |__| \/ \/ | |||
| // PullRequestPayload represents a payload information of pull request event. | |||
| type PullRequestPayload struct { | |||
| Secret string `json:"secret"` | |||
| Action HookIssueAction `json:"action"` | |||
| Index int64 `json:"number"` | |||
| Changes *ChangesPayload `json:"changes,omitempty"` | |||
| PullRequest *PullRequest `json:"pull_request"` | |||
| Repository *Repository `json:"repository"` | |||
| Sender *User `json:"sender"` | |||
| } | |||
| func (p *PullRequestPayload) SetSecret(secret string) { | |||
| p.Secret = secret | |||
| } | |||
| func (p *PullRequestPayload) JSONPayload() ([]byte, error) { | |||
| return json.MarshalIndent(p, "", " ") | |||
| } | |||
| @@ -0,0 +1,50 @@ | |||
| // Copyright 2015 The Gogs Authors. All rights reserved. | |||
| // Use of this source code is governed by a MIT-style | |||
| // license that can be found in the LICENSE file. | |||
| package gitea | |||
| import ( | |||
| "bytes" | |||
| "encoding/json" | |||
| "fmt" | |||
| "time" | |||
| ) | |||
| type DeployKey struct { | |||
| ID int64 `json:"id"` | |||
| Key string `json:"key"` | |||
| URL string `json:"url"` | |||
| Title string `json:"title"` | |||
| Created time.Time `json:"created_at"` | |||
| ReadOnly bool `json:"read_only"` | |||
| } | |||
| func (c *Client) ListDeployKeys(user, repo string) ([]*DeployKey, error) { | |||
| keys := make([]*DeployKey, 0, 10) | |||
| return keys, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/keys", user, repo), nil, nil, &keys) | |||
| } | |||
| func (c *Client) GetDeployKey(user, repo string, keyID int64) (*DeployKey, error) { | |||
| key := new(DeployKey) | |||
| return key, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/keys/%d", user, repo, keyID), nil, nil, &key) | |||
| } | |||
| type CreateKeyOption struct { | |||
| Title string `json:"title" binding:"Required"` | |||
| Key string `json:"key" binding:"Required"` | |||
| } | |||
| func (c *Client) CreateDeployKey(user, repo string, opt CreateKeyOption) (*DeployKey, error) { | |||
| body, err := json.Marshal(&opt) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| key := new(DeployKey) | |||
| return key, c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/keys", user, repo), jsonHeader, bytes.NewReader(body), key) | |||
| } | |||
| func (c *Client) DeleteDeployKey(owner, repo string, keyID int64) error { | |||
| _, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/keys/%d", owner, repo, keyID), nil, nil) | |||
| return err | |||
| } | |||
| @@ -0,0 +1,24 @@ | |||
| // Copyright 2014 The Gogs Authors. All rights reserved. | |||
| // Use of this source code is governed by a MIT-style | |||
| // license that can be found in the LICENSE file. | |||
| package gitea | |||
| import ( | |||
| "fmt" | |||
| ) | |||
| // User represents a API user. | |||
| type User struct { | |||
| ID int64 `json:"id"` | |||
| UserName string `json:"username"` | |||
| FullName string `json:"full_name"` | |||
| Email string `json:"email"` | |||
| AvatarUrl string `json:"avatar_url"` | |||
| } | |||
| func (c *Client) GetUserInfo(user string) (*User, error) { | |||
| u := new(User) | |||
| err := c.getParsedResponse("GET", fmt.Sprintf("/users/%s", user), nil, nil, u) | |||
| return u, err | |||
| } | |||
| @@ -0,0 +1,46 @@ | |||
| // Copyright 2014 The Gogs Authors. All rights reserved. | |||
| // Use of this source code is governed by a MIT-style | |||
| // license that can be found in the LICENSE file. | |||
| package gitea | |||
| import ( | |||
| "bytes" | |||
| "encoding/base64" | |||
| "encoding/json" | |||
| "fmt" | |||
| "net/http" | |||
| ) | |||
| func BasicAuthEncode(user, pass string) string { | |||
| return base64.StdEncoding.EncodeToString([]byte(user + ":" + pass)) | |||
| } | |||
| // AccessToken represents a API access token. | |||
| type AccessToken struct { | |||
| Name string `json:"name"` | |||
| Sha1 string `json:"sha1"` | |||
| } | |||
| func (c *Client) ListAccessTokens(user, pass string) ([]*AccessToken, error) { | |||
| tokens := make([]*AccessToken, 0, 10) | |||
| return tokens, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/tokens", user), | |||
| http.Header{"Authorization": []string{"Basic " + BasicAuthEncode(user, pass)}}, nil, &tokens) | |||
| } | |||
| type CreateAccessTokenOption struct { | |||
| Name string `json:"name" binding:"Required"` | |||
| } | |||
| func (c *Client) CreateAccessToken(user, pass string, opt CreateAccessTokenOption) (*AccessToken, error) { | |||
| body, err := json.Marshal(&opt) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| t := new(AccessToken) | |||
| return t, c.getParsedResponse("POST", fmt.Sprintf("/users/%s/tokens", user), | |||
| http.Header{ | |||
| "content-type": []string{"application/json"}, | |||
| "Authorization": []string{"Basic " + BasicAuthEncode(user, pass)}}, | |||
| bytes.NewReader(body), t) | |||
| } | |||
| @@ -0,0 +1,43 @@ | |||
| // Copyright 2015 The Gogs Authors. All rights reserved. | |||
| // Use of this source code is governed by a MIT-style | |||
| // license that can be found in the LICENSE file. | |||
| package gitea | |||
| import ( | |||
| "bytes" | |||
| "encoding/json" | |||
| ) | |||
| type Email struct { | |||
| Email string `json:"email"` | |||
| Verified bool `json:"verified"` | |||
| Primary bool `json:"primary"` | |||
| } | |||
| func (c *Client) ListEmails() ([]*Email, error) { | |||
| emails := make([]*Email, 0, 3) | |||
| return emails, c.getParsedResponse("GET", "/user/emails", nil, nil, &emails) | |||
| } | |||
| type CreateEmailOption struct { | |||
| Emails []string `json:"emails"` | |||
| } | |||
| func (c *Client) AddEmail(opt CreateEmailOption) ([]*Email, error) { | |||
| body, err := json.Marshal(&opt) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| emails := make([]*Email, 0, 3) | |||
| return emails, c.getParsedResponse("POST", "/user/emails", jsonHeader, bytes.NewReader(body), emails) | |||
| } | |||
| func (c *Client) DeleteEmail(opt CreateEmailOption) error { | |||
| body, err := json.Marshal(&opt) | |||
| if err != nil { | |||
| return err | |||
| } | |||
| _, err = c.getResponse("DELETE", "/user/emails", jsonHeader, bytes.NewReader(body)) | |||
| return err | |||
| } | |||
| @@ -0,0 +1,47 @@ | |||
| // Copyright 2015 The Gogs Authors. All rights reserved. | |||
| // Use of this source code is governed by a MIT-style | |||
| // license that can be found in the LICENSE file. | |||
| package gitea | |||
| import "fmt" | |||
| func (c *Client) ListMyFollowers(page int) ([]*User, error) { | |||
| users := make([]*User, 0, 10) | |||
| return users, c.getParsedResponse("GET", fmt.Sprintf("/user/followers?page=%d", page), nil, nil, &users) | |||
| } | |||
| func (c *Client) ListFollowers(user string, page int) ([]*User, error) { | |||
| users := make([]*User, 0, 10) | |||
| return users, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/followers?page=%d", user, page), nil, nil, &users) | |||
| } | |||
| func (c *Client) ListMyFollowing(page int) ([]*User, error) { | |||
| users := make([]*User, 0, 10) | |||
| return users, c.getParsedResponse("GET", fmt.Sprintf("/user/following?page=%d", page), nil, nil, &users) | |||
| } | |||
| func (c *Client) ListFollowing(user string, page int) ([]*User, error) { | |||
| users := make([]*User, 0, 10) | |||
| return users, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/following?page=%d", user, page), nil, nil, &users) | |||
| } | |||
| func (c *Client) IsFollowing(target string) bool { | |||
| _, err := c.getResponse("GET", fmt.Sprintf("/user/following/%s", target), nil, nil) | |||
| return err == nil | |||
| } | |||
| func (c *Client) IsUserFollowing(user, target string) bool { | |||
| _, err := c.getResponse("GET", fmt.Sprintf("/users/%s/following/%s", user, target), nil, nil) | |||
| return err == nil | |||
| } | |||
| func (c *Client) Follow(target string) error { | |||
| _, err := c.getResponse("PUT", fmt.Sprintf("/user/following/%s", target), nil, nil) | |||
| return err | |||
| } | |||
| func (c *Client) Unfollow(target string) error { | |||
| _, err := c.getResponse("DELETE", fmt.Sprintf("/user/following/%s", target), nil, nil) | |||
| return err | |||
| } | |||
| @@ -0,0 +1,49 @@ | |||
| // Copyright 2015 The Gogs Authors. All rights reserved. | |||
| // Use of this source code is governed by a MIT-style | |||
| // license that can be found in the LICENSE file. | |||
| package gitea | |||
| import ( | |||
| "bytes" | |||
| "encoding/json" | |||
| "fmt" | |||
| "time" | |||
| ) | |||
| type PublicKey struct { | |||
| ID int64 `json:"id"` | |||
| Key string `json:"key"` | |||
| URL string `json:"url,omitempty"` | |||
| Title string `json:"title,omitempty"` | |||
| Created time.Time `json:"created_at,omitempty"` | |||
| } | |||
| func (c *Client) ListPublicKeys(user string) ([]*PublicKey, error) { | |||
| keys := make([]*PublicKey, 0, 10) | |||
| return keys, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/keys", user), nil, nil, &keys) | |||
| } | |||
| func (c *Client) ListMyPublicKeys() ([]*PublicKey, error) { | |||
| keys := make([]*PublicKey, 0, 10) | |||
| return keys, c.getParsedResponse("GET", "/user/keys", nil, nil, &keys) | |||
| } | |||
| func (c *Client) GetPublicKey(keyID int64) (*PublicKey, error) { | |||
| key := new(PublicKey) | |||
| return key, c.getParsedResponse("GET", fmt.Sprintf("/user/keys/%d", keyID), nil, nil, &key) | |||
| } | |||
| func (c *Client) CreatePublicKey(opt CreateKeyOption) (*PublicKey, error) { | |||
| body, err := json.Marshal(&opt) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| key := new(PublicKey) | |||
| return key, c.getParsedResponse("POST", "/user/keys", jsonHeader, bytes.NewReader(body), key) | |||
| } | |||
| func (c *Client) DeletePublicKey(keyID int64) error { | |||
| _, err := c.getResponse("DELETE", fmt.Sprintf("/user/keys/%d", keyID), nil, nil) | |||
| return err | |||
| } | |||
| @@ -0,0 +1,23 @@ | |||
| // Copyright 2015 The Gogs Authors. All rights reserved. | |||
| // Use of this source code is governed by a MIT-style | |||
| // license that can be found in the LICENSE file. | |||
| package gitea | |||
| import ( | |||
| "net/http" | |||
| ) | |||
| var jsonHeader = http.Header{"content-type": []string{"application/json"}} | |||
| func Bool(v bool) *bool { | |||
| return &v | |||
| } | |||
| func String(v string) *string { | |||
| return &v | |||
| } | |||
| func Int64(v int64) *int64 { | |||
| return &v | |||
| } | |||
| @@ -44,6 +44,12 @@ | |||
| "revision": "766747ef8b271a2b1142edd0a40735f556ec2c1d", | |||
| "revisionTime": "2016-11-06T09:52:37Z" | |||
| }, | |||
| { | |||
| "checksumSHA1": "/uhZZppDeb3Rbp3h8C0ALR3hdrA=", | |||
| "path": "github.com/go-gitea/go-sdk/gitea", | |||
| "revision": "0a0a04ccf7a5e6b93d9a5507701635330cf4579c", | |||
| "revisionTime": "2016-11-07T15:06:50Z" | |||
| }, | |||
| { | |||
| "checksumSHA1": "qM/kf31cT2cxjtHxdzbu8q8jPq0=", | |||
| "path": "github.com/go-macaron/binding", | |||