* Add info about list endpoints to CONTRIBUTING.md * Let all list endpoints return X-Total-Count header * Add TODOs for GetCombinedCommitStatusByRef * Fix models/issue_stopwatch.go * Rrefactor models.ListDeployKeys * Introduce helper func and use them for SetLinkHeader related functags/v1.16.0-rc1
An endpoint which changes/edits an object expects all fields to be optional (except ones to identify the object, which are required). | An endpoint which changes/edits an object expects all fields to be optional (except ones to identify the object, which are required). | ||||
### Endpoints returning lists should | |||||
* support pagination (`page` & `limit` options in query) | |||||
* set `X-Total-Count` header via **SetTotalCountHeader** ([example](https://github.com/go-gitea/gitea/blob/7aae98cc5d4113f1e9918b7ee7dd09f67c189e3e/routers/api/v1/repo/issue.go#L444)) | |||||
## Developer Certificate of Origin (DCO) | ## Developer Certificate of Origin (DCO) | ||||
minor release every three or four months, which breaks down into two or three months of | minor release every three or four months, which breaks down into two or three months of | ||||
general development followed by one month of testing and polishing | general development followed by one month of testing and polishing | ||||
known as the release freeze. All the feature pull requests should be | known as the release freeze. All the feature pull requests should be | ||||
merged before feature freeze. And, during the frozen period, a corresponding | |||||
release branch is open for fixes backported from main branch. Release candidates | |||||
merged before feature freeze. And, during the frozen period, a corresponding | |||||
release branch is open for fixes backported from main branch. Release candidates | |||||
are made during this period for user testing to | are made during this period for user testing to | ||||
obtain a final version that is maintained in this branch. A release is | obtain a final version that is maintained in this branch. A release is | ||||
maintained by issuing patch releases to only correct critical problems | maintained by issuing patch releases to only correct critical problems |
resp := session.MakeRequest(t, req, http.StatusOK) | resp := session.MakeRequest(t, req, http.StatusOK) | ||||
var apiTimes api.TrackedTimeList | var apiTimes api.TrackedTimeList | ||||
DecodeJSON(t, resp, &apiTimes) | DecodeJSON(t, resp, &apiTimes) | ||||
expect, err := models.GetTrackedTimes(models.FindTrackedTimesOptions{IssueID: issue2.ID}) | |||||
expect, err := models.GetTrackedTimes(&models.FindTrackedTimesOptions{IssueID: issue2.ID}) | |||||
assert.NoError(t, err) | assert.NoError(t, err) | ||||
assert.Len(t, apiTimes, 3) | assert.Len(t, apiTimes, 3) | ||||
import ( | import ( | ||||
"fmt" | "fmt" | ||||
"net/http" | "net/http" | ||||
"net/url" | |||||
"testing" | "testing" | ||||
"code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
"github.com/stretchr/testify/assert" | "github.com/stretchr/testify/assert" | ||||
) | ) | ||||
func TestAPITopicSearch(t *testing.T) { | |||||
defer prepareTestEnv(t)() | |||||
searchURL, _ := url.Parse("/api/v1/topics/search") | |||||
var topics struct { | |||||
TopicNames []*api.TopicResponse `json:"topics"` | |||||
} | |||||
query := url.Values{"page": []string{"1"}, "limit": []string{"4"}} | |||||
searchURL.RawQuery = query.Encode() | |||||
res := MakeRequest(t, NewRequest(t, "GET", searchURL.String()), http.StatusOK) | |||||
DecodeJSON(t, res, &topics) | |||||
assert.Len(t, topics.TopicNames, 4) | |||||
assert.EqualValues(t, "6", res.Header().Get("x-total-count")) | |||||
query.Add("q", "topic") | |||||
searchURL.RawQuery = query.Encode() | |||||
res = MakeRequest(t, NewRequest(t, "GET", searchURL.String()), http.StatusOK) | |||||
DecodeJSON(t, res, &topics) | |||||
assert.Len(t, topics.TopicNames, 2) | |||||
query.Set("q", "database") | |||||
searchURL.RawQuery = query.Encode() | |||||
res = MakeRequest(t, NewRequest(t, "GET", searchURL.String()), http.StatusOK) | |||||
DecodeJSON(t, res, &topics) | |||||
if assert.Len(t, topics.TopicNames, 1) { | |||||
assert.EqualValues(t, 2, topics.TopicNames[0].ID) | |||||
assert.EqualValues(t, "database", topics.TopicNames[0].Name) | |||||
assert.EqualValues(t, 1, topics.TopicNames[0].RepoCount) | |||||
} | |||||
} | |||||
func TestAPIRepoTopic(t *testing.T) { | func TestAPIRepoTopic(t *testing.T) { | ||||
defer prepareTestEnv(t)() | defer prepareTestEnv(t)() | ||||
user2 := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User) // owner of repo2 | user2 := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User) // owner of repo2 |
return fmt.Errorf("refreshCollaboratorAccesses: %v", err) | return fmt.Errorf("refreshCollaboratorAccesses: %v", err) | ||||
} | } | ||||
if err = repo.Owner.getTeams(e); err != nil { | |||||
if err = repo.Owner.loadTeams(e); err != nil { | |||||
return err | return err | ||||
} | } | ||||
if len(ids) == 0 { | if len(ids) == 0 { | ||||
return statuses, nil | return statuses, nil | ||||
} | } | ||||
return statuses, x.In("id", ids).Find(&statuses) | |||||
return statuses, e.In("id", ids).Find(&statuses) | |||||
} | } | ||||
// FindRepoRecentCommitStatusContexts returns repository's recent commit status contexts | // FindRepoRecentCommitStatusContexts returns repository's recent commit status contexts |
return keys, sess.Find(&keys) | return keys, sess.Find(&keys) | ||||
} | } | ||||
// CountUserGPGKeys return number of gpg keys a user own | |||||
func CountUserGPGKeys(userID int64) (int64, error) { | |||||
return x.Where("owner_id=? AND primary_key_id=''", userID).Count(&GPGKey{}) | |||||
} | |||||
// GetGPGKeyByID returns public key by given ID. | // GetGPGKeyByID returns public key by given ID. | ||||
func GetGPGKeyByID(keyID int64) (*GPGKey, error) { | func GetGPGKeyByID(keyID int64) (*GPGKey, error) { | ||||
key := new(GPGKey) | key := new(GPGKey) |
func (issue *Issue) loadTotalTimes(e Engine) (err error) { | func (issue *Issue) loadTotalTimes(e Engine) (err error) { | ||||
opts := FindTrackedTimesOptions{IssueID: issue.ID} | opts := FindTrackedTimesOptions{IssueID: issue.ID} | ||||
issue.TotalTrackedTime, err = opts.ToSession(e).SumInt(&TrackedTime{}, "time") | |||||
issue.TotalTrackedTime, err = opts.toSession(e).SumInt(&TrackedTime{}, "time") | |||||
if err != nil { | if err != nil { | ||||
return err | return err | ||||
} | } | ||||
if issue.Comments != nil { | if issue.Comments != nil { | ||||
return nil | return nil | ||||
} | } | ||||
issue.Comments, err = findComments(e, FindCommentsOptions{ | |||||
issue.Comments, err = findComments(e, &FindCommentsOptions{ | |||||
IssueID: issue.ID, | IssueID: issue.ID, | ||||
Type: tp, | Type: tp, | ||||
}) | }) |
return cond | return cond | ||||
} | } | ||||
func findComments(e Engine, opts FindCommentsOptions) ([]*Comment, error) { | |||||
func findComments(e Engine, opts *FindCommentsOptions) ([]*Comment, error) { | |||||
comments := make([]*Comment, 0, 10) | comments := make([]*Comment, 0, 10) | ||||
sess := e.Where(opts.toConds()) | sess := e.Where(opts.toConds()) | ||||
if opts.RepoID > 0 { | if opts.RepoID > 0 { | ||||
} | } | ||||
// FindComments returns all comments according options | // FindComments returns all comments according options | ||||
func FindComments(opts FindCommentsOptions) ([]*Comment, error) { | |||||
func FindComments(opts *FindCommentsOptions) ([]*Comment, error) { | |||||
return findComments(x, opts) | return findComments(x, opts) | ||||
} | } | ||||
// CountComments count all comments according options by ignoring pagination | |||||
func CountComments(opts *FindCommentsOptions) (int64, error) { | |||||
sess := x.Where(opts.toConds()) | |||||
if opts.RepoID > 0 { | |||||
sess.Join("INNER", "issue", "issue.id = comment.issue_id") | |||||
} | |||||
return sess.Count(&Comment{}) | |||||
} | |||||
// UpdateComment updates information of comment. | // UpdateComment updates information of comment. | ||||
func UpdateComment(c *Comment, doer *User) error { | func UpdateComment(c *Comment, doer *User) error { | ||||
sess := x.NewSession() | sess := x.NewSession() |
return getLabelsByRepoID(x, repoID, sortType, listOptions) | return getLabelsByRepoID(x, repoID, sortType, listOptions) | ||||
} | } | ||||
// CountLabelsByRepoID count number of all labels that belong to given repository by ID. | |||||
func CountLabelsByRepoID(repoID int64) (int64, error) { | |||||
return x.Where("repo_id = ?", repoID).Count(&Label{}) | |||||
} | |||||
// ________ | // ________ | ||||
// \_____ \_______ ____ | // \_____ \_______ ____ | ||||
// / | \_ __ \/ ___\ | // / | \_ __ \/ ___\ | ||||
return getLabelsByOrgID(x, orgID, sortType, listOptions) | return getLabelsByOrgID(x, orgID, sortType, listOptions) | ||||
} | } | ||||
// CountLabelsByOrgID count all labels that belong to given organization by ID. | |||||
func CountLabelsByOrgID(orgID int64) (int64, error) { | |||||
return x.Where("org_id = ?", orgID).Count(&Label{}) | |||||
} | |||||
// .___ | // .___ | ||||
// | | ______ ________ __ ____ | // | | ______ ________ __ ____ | ||||
// | |/ ___// ___/ | \_/ __ \ | // | |/ ___// ___/ | \_/ __ \ |
SortType string | SortType string | ||||
} | } | ||||
// GetMilestones returns milestones filtered by GetMilestonesOption's | |||||
func GetMilestones(opts GetMilestonesOption) (MilestoneList, error) { | |||||
sess := x.Where("repo_id = ?", opts.RepoID) | |||||
func (opts GetMilestonesOption) toCond() builder.Cond { | |||||
cond := builder.NewCond() | |||||
if opts.RepoID != 0 { | |||||
cond = cond.And(builder.Eq{"repo_id": opts.RepoID}) | |||||
} | |||||
switch opts.State { | switch opts.State { | ||||
case api.StateClosed: | case api.StateClosed: | ||||
sess = sess.And("is_closed = ?", true) | |||||
cond = cond.And(builder.Eq{"is_closed": true}) | |||||
case api.StateAll: | case api.StateAll: | ||||
break | break | ||||
// api.StateOpen: | // api.StateOpen: | ||||
default: | default: | ||||
sess = sess.And("is_closed = ?", false) | |||||
cond = cond.And(builder.Eq{"is_closed": false}) | |||||
} | } | ||||
if len(opts.Name) != 0 { | if len(opts.Name) != 0 { | ||||
sess = sess.And(builder.Like{"name", opts.Name}) | |||||
cond = cond.And(builder.Like{"name", opts.Name}) | |||||
} | } | ||||
return cond | |||||
} | |||||
// GetMilestones returns milestones filtered by GetMilestonesOption's | |||||
func GetMilestones(opts GetMilestonesOption) (MilestoneList, int64, error) { | |||||
sess := x.Where(opts.toCond()) | |||||
if opts.Page != 0 { | if opts.Page != 0 { | ||||
sess = opts.setSessionPagination(sess) | sess = opts.setSessionPagination(sess) | ||||
} | } | ||||
} | } | ||||
miles := make([]*Milestone, 0, opts.PageSize) | miles := make([]*Milestone, 0, opts.PageSize) | ||||
return miles, sess.Find(&miles) | |||||
total, err := sess.FindAndCount(&miles) | |||||
return miles, total, err | |||||
} | } | ||||
// SearchMilestones search milestones | // SearchMilestones search milestones |
assert.NoError(t, PrepareTestDatabase()) | assert.NoError(t, PrepareTestDatabase()) | ||||
test := func(repoID int64, state api.StateType) { | test := func(repoID int64, state api.StateType) { | ||||
repo := AssertExistsAndLoadBean(t, &Repository{ID: repoID}).(*Repository) | repo := AssertExistsAndLoadBean(t, &Repository{ID: repoID}).(*Repository) | ||||
milestones, err := GetMilestones(GetMilestonesOption{ | |||||
milestones, _, err := GetMilestones(GetMilestonesOption{ | |||||
RepoID: repo.ID, | RepoID: repo.ID, | ||||
State: state, | State: state, | ||||
}) | }) | ||||
test(3, api.StateClosed) | test(3, api.StateClosed) | ||||
test(3, api.StateAll) | test(3, api.StateAll) | ||||
milestones, err := GetMilestones(GetMilestonesOption{ | |||||
milestones, _, err := GetMilestones(GetMilestonesOption{ | |||||
RepoID: NonexistentID, | RepoID: NonexistentID, | ||||
State: api.StateOpen, | State: api.StateOpen, | ||||
}) | }) | ||||
repo := AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository) | repo := AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository) | ||||
test := func(sortType string, sortCond func(*Milestone) int) { | test := func(sortType string, sortCond func(*Milestone) int) { | ||||
for _, page := range []int{0, 1} { | for _, page := range []int{0, 1} { | ||||
milestones, err := GetMilestones(GetMilestonesOption{ | |||||
milestones, _, err := GetMilestones(GetMilestonesOption{ | |||||
ListOptions: ListOptions{ | ListOptions: ListOptions{ | ||||
Page: page, | Page: page, | ||||
PageSize: setting.UI.IssuePagingNum, | PageSize: setting.UI.IssuePagingNum, | ||||
} | } | ||||
assert.True(t, sort.IntsAreSorted(values)) | assert.True(t, sort.IntsAreSorted(values)) | ||||
milestones, err = GetMilestones(GetMilestonesOption{ | |||||
milestones, _, err = GetMilestones(GetMilestonesOption{ | |||||
ListOptions: ListOptions{ | ListOptions: ListOptions{ | ||||
Page: page, | Page: page, | ||||
PageSize: setting.UI.IssuePagingNum, | PageSize: setting.UI.IssuePagingNum, |
return sws, nil | return sws, nil | ||||
} | } | ||||
// CountUserStopwatches return count of all stopwatches of a user | |||||
func CountUserStopwatches(userID int64) (int64, error) { | |||||
return x.Where("user_id = ?", userID).Count(&Stopwatch{}) | |||||
} | |||||
// StopwatchExists returns true if the stopwatch exists | // StopwatchExists returns true if the stopwatch exists | ||||
func StopwatchExists(userID, issueID int64) bool { | func StopwatchExists(userID, issueID int64) bool { | ||||
_, exists, _ := getStopwatch(x, userID, issueID) | _, exists, _ := getStopwatch(x, userID, issueID) |
CreatedBeforeUnix int64 | CreatedBeforeUnix int64 | ||||
} | } | ||||
// ToCond will convert each condition into a xorm-Cond | |||||
func (opts *FindTrackedTimesOptions) ToCond() builder.Cond { | |||||
// toCond will convert each condition into a xorm-Cond | |||||
func (opts *FindTrackedTimesOptions) toCond() builder.Cond { | |||||
cond := builder.NewCond().And(builder.Eq{"tracked_time.deleted": false}) | cond := builder.NewCond().And(builder.Eq{"tracked_time.deleted": false}) | ||||
if opts.IssueID != 0 { | if opts.IssueID != 0 { | ||||
cond = cond.And(builder.Eq{"issue_id": opts.IssueID}) | cond = cond.And(builder.Eq{"issue_id": opts.IssueID}) | ||||
return cond | return cond | ||||
} | } | ||||
// ToSession will convert the given options to a xorm Session by using the conditions from ToCond and joining with issue table if required | |||||
func (opts *FindTrackedTimesOptions) ToSession(e Engine) Engine { | |||||
// toSession will convert the given options to a xorm Session by using the conditions from toCond and joining with issue table if required | |||||
func (opts *FindTrackedTimesOptions) toSession(e Engine) Engine { | |||||
sess := e | sess := e | ||||
if opts.RepositoryID > 0 || opts.MilestoneID > 0 { | if opts.RepositoryID > 0 || opts.MilestoneID > 0 { | ||||
sess = e.Join("INNER", "issue", "issue.id = tracked_time.issue_id") | sess = e.Join("INNER", "issue", "issue.id = tracked_time.issue_id") | ||||
} | } | ||||
sess = sess.Where(opts.ToCond()) | |||||
sess = sess.Where(opts.toCond()) | |||||
if opts.Page != 0 { | if opts.Page != 0 { | ||||
sess = opts.setEnginePagination(sess) | sess = opts.setEnginePagination(sess) | ||||
return sess | return sess | ||||
} | } | ||||
func getTrackedTimes(e Engine, options FindTrackedTimesOptions) (trackedTimes TrackedTimeList, err error) { | |||||
err = options.ToSession(e).Find(&trackedTimes) | |||||
func getTrackedTimes(e Engine, options *FindTrackedTimesOptions) (trackedTimes TrackedTimeList, err error) { | |||||
err = options.toSession(e).Find(&trackedTimes) | |||||
return | return | ||||
} | } | ||||
// GetTrackedTimes returns all tracked times that fit to the given options. | // GetTrackedTimes returns all tracked times that fit to the given options. | ||||
func GetTrackedTimes(opts FindTrackedTimesOptions) (TrackedTimeList, error) { | |||||
func GetTrackedTimes(opts *FindTrackedTimesOptions) (TrackedTimeList, error) { | |||||
return getTrackedTimes(x, opts) | return getTrackedTimes(x, opts) | ||||
} | } | ||||
// CountTrackedTimes returns count of tracked times that fit to the given options. | |||||
func CountTrackedTimes(opts *FindTrackedTimesOptions) (int64, error) { | |||||
sess := x.Where(opts.toCond()) | |||||
if opts.RepositoryID > 0 || opts.MilestoneID > 0 { | |||||
sess = sess.Join("INNER", "issue", "issue.id = tracked_time.issue_id") | |||||
} | |||||
return sess.Count(&TrackedTime{}) | |||||
} | |||||
func getTrackedSeconds(e Engine, opts FindTrackedTimesOptions) (trackedSeconds int64, err error) { | func getTrackedSeconds(e Engine, opts FindTrackedTimesOptions) (trackedSeconds int64, err error) { | ||||
return opts.ToSession(e).SumInt(&TrackedTime{}, "time") | |||||
return opts.toSession(e).SumInt(&TrackedTime{}, "time") | |||||
} | } | ||||
// GetTrackedSeconds return sum of seconds | // GetTrackedSeconds return sum of seconds | ||||
} | } | ||||
// TotalTimes returns the spent time for each user by an issue | // TotalTimes returns the spent time for each user by an issue | ||||
func TotalTimes(options FindTrackedTimesOptions) (map[*User]string, error) { | |||||
func TotalTimes(options *FindTrackedTimesOptions) (map[*User]string, error) { | |||||
trackedTimes, err := GetTrackedTimes(options) | trackedTimes, err := GetTrackedTimes(options) | ||||
if err != nil { | if err != nil { | ||||
return nil, err | return nil, err | ||||
return | return | ||||
} | } | ||||
_, err = opts.ToSession(e).Table("tracked_time").Cols("deleted").Update(&TrackedTime{Deleted: true}) | |||||
_, err = opts.toSession(e).Table("tracked_time").Cols("deleted").Update(&TrackedTime{Deleted: true}) | |||||
return | return | ||||
} | } | ||||
assert.NoError(t, PrepareTestDatabase()) | assert.NoError(t, PrepareTestDatabase()) | ||||
// by Issue | // by Issue | ||||
times, err := GetTrackedTimes(FindTrackedTimesOptions{IssueID: 1}) | |||||
times, err := GetTrackedTimes(&FindTrackedTimesOptions{IssueID: 1}) | |||||
assert.NoError(t, err) | assert.NoError(t, err) | ||||
assert.Len(t, times, 1) | assert.Len(t, times, 1) | ||||
assert.Equal(t, int64(400), times[0].Time) | assert.Equal(t, int64(400), times[0].Time) | ||||
times, err = GetTrackedTimes(FindTrackedTimesOptions{IssueID: -1}) | |||||
times, err = GetTrackedTimes(&FindTrackedTimesOptions{IssueID: -1}) | |||||
assert.NoError(t, err) | assert.NoError(t, err) | ||||
assert.Len(t, times, 0) | assert.Len(t, times, 0) | ||||
// by User | // by User | ||||
times, err = GetTrackedTimes(FindTrackedTimesOptions{UserID: 1}) | |||||
times, err = GetTrackedTimes(&FindTrackedTimesOptions{UserID: 1}) | |||||
assert.NoError(t, err) | assert.NoError(t, err) | ||||
assert.Len(t, times, 3) | assert.Len(t, times, 3) | ||||
assert.Equal(t, int64(400), times[0].Time) | assert.Equal(t, int64(400), times[0].Time) | ||||
times, err = GetTrackedTimes(FindTrackedTimesOptions{UserID: 3}) | |||||
times, err = GetTrackedTimes(&FindTrackedTimesOptions{UserID: 3}) | |||||
assert.NoError(t, err) | assert.NoError(t, err) | ||||
assert.Len(t, times, 0) | assert.Len(t, times, 0) | ||||
// by Repo | // by Repo | ||||
times, err = GetTrackedTimes(FindTrackedTimesOptions{RepositoryID: 2}) | |||||
times, err = GetTrackedTimes(&FindTrackedTimesOptions{RepositoryID: 2}) | |||||
assert.NoError(t, err) | assert.NoError(t, err) | ||||
assert.Len(t, times, 3) | assert.Len(t, times, 3) | ||||
assert.Equal(t, int64(1), times[0].Time) | assert.Equal(t, int64(1), times[0].Time) | ||||
assert.NoError(t, err) | assert.NoError(t, err) | ||||
assert.Equal(t, issue.RepoID, int64(2)) | assert.Equal(t, issue.RepoID, int64(2)) | ||||
times, err = GetTrackedTimes(FindTrackedTimesOptions{RepositoryID: 1}) | |||||
times, err = GetTrackedTimes(&FindTrackedTimesOptions{RepositoryID: 1}) | |||||
assert.NoError(t, err) | assert.NoError(t, err) | ||||
assert.Len(t, times, 5) | assert.Len(t, times, 5) | ||||
times, err = GetTrackedTimes(FindTrackedTimesOptions{RepositoryID: 10}) | |||||
times, err = GetTrackedTimes(&FindTrackedTimesOptions{RepositoryID: 10}) | |||||
assert.NoError(t, err) | assert.NoError(t, err) | ||||
assert.Len(t, times, 0) | assert.Len(t, times, 0) | ||||
} | } | ||||
func TestTotalTimes(t *testing.T) { | func TestTotalTimes(t *testing.T) { | ||||
assert.NoError(t, PrepareTestDatabase()) | assert.NoError(t, PrepareTestDatabase()) | ||||
total, err := TotalTimes(FindTrackedTimesOptions{IssueID: 1}) | |||||
total, err := TotalTimes(&FindTrackedTimesOptions{IssueID: 1}) | |||||
assert.NoError(t, err) | assert.NoError(t, err) | ||||
assert.Len(t, total, 1) | assert.Len(t, total, 1) | ||||
for user, time := range total { | for user, time := range total { | ||||
assert.Equal(t, "6min 40s", time) | assert.Equal(t, "6min 40s", time) | ||||
} | } | ||||
total, err = TotalTimes(FindTrackedTimesOptions{IssueID: 2}) | |||||
total, err = TotalTimes(&FindTrackedTimesOptions{IssueID: 2}) | |||||
assert.NoError(t, err) | assert.NoError(t, err) | ||||
assert.Len(t, total, 2) | assert.Len(t, total, 2) | ||||
for user, time := range total { | for user, time := range total { | ||||
} | } | ||||
} | } | ||||
total, err = TotalTimes(FindTrackedTimesOptions{IssueID: 5}) | |||||
total, err = TotalTimes(&FindTrackedTimesOptions{IssueID: 5}) | |||||
assert.NoError(t, err) | assert.NoError(t, err) | ||||
assert.Len(t, total, 1) | assert.Len(t, total, 1) | ||||
for user, time := range total { | for user, time := range total { | ||||
assert.Equal(t, "1s", time) | assert.Equal(t, "1s", time) | ||||
} | } | ||||
total, err = TotalTimes(FindTrackedTimesOptions{IssueID: 4}) | |||||
total, err = TotalTimes(&FindTrackedTimesOptions{IssueID: 4}) | |||||
assert.NoError(t, err) | assert.NoError(t, err) | ||||
assert.Len(t, total, 2) | assert.Len(t, total, 2) | ||||
} | } |
return getNotifications(x, opts) | return getNotifications(x, opts) | ||||
} | } | ||||
// CountNotifications count all notifications that fit to the given options and ignore pagination. | |||||
func CountNotifications(opts *FindNotificationOptions) (int64, error) { | |||||
return x.Where(opts.ToCond()).Count(&Notification{}) | |||||
} | |||||
// CreateRepoTransferNotification creates notification for the user a repository was transferred to | // CreateRepoTransferNotification creates notification for the user a repository was transferred to | ||||
func CreateRepoTransferNotification(doer, newOwner *User, repo *Repository) error { | func CreateRepoTransferNotification(doer, newOwner *User, repo *Repository) error { | ||||
sess := x.NewSession() | sess := x.NewSession() |
} | } | ||||
// ListOAuth2Applications returns a list of oauth2 applications belongs to given user. | // ListOAuth2Applications returns a list of oauth2 applications belongs to given user. | ||||
func ListOAuth2Applications(uid int64, listOptions ListOptions) ([]*OAuth2Application, error) { | |||||
func ListOAuth2Applications(uid int64, listOptions ListOptions) ([]*OAuth2Application, int64, error) { | |||||
sess := x. | sess := x. | ||||
Where("uid=?", uid). | Where("uid=?", uid). | ||||
Desc("id") | Desc("id") | ||||
sess = listOptions.setSessionPagination(sess) | sess = listOptions.setSessionPagination(sess) | ||||
apps := make([]*OAuth2Application, 0, listOptions.PageSize) | apps := make([]*OAuth2Application, 0, listOptions.PageSize) | ||||
return apps, sess.Find(&apps) | |||||
total, err := sess.FindAndCount(&apps) | |||||
return apps, total, err | |||||
} | } | ||||
apps := make([]*OAuth2Application, 0, 5) | apps := make([]*OAuth2Application, 0, 5) | ||||
return apps, sess.Find(&apps) | |||||
total, err := sess.FindAndCount(&apps) | |||||
return apps, total, err | |||||
} | } | ||||
////////////////////////////////////////////////////// | ////////////////////////////////////////////////////// |
return org.getOwnerTeam(x) | return org.getOwnerTeam(x) | ||||
} | } | ||||
func (org *User) getTeams(e Engine) error { | |||||
func (org *User) loadTeams(e Engine) error { | |||||
if org.Teams != nil { | if org.Teams != nil { | ||||
return nil | return nil | ||||
} | } | ||||
Find(&org.Teams) | Find(&org.Teams) | ||||
} | } | ||||
// GetTeams returns paginated teams that belong to organization. | |||||
func (org *User) GetTeams(opts *SearchTeamOptions) error { | |||||
if opts.Page != 0 { | |||||
return org.getTeams(opts.getPaginatedSession()) | |||||
} | |||||
return org.getTeams(x) | |||||
// LoadTeams load teams if not loaded. | |||||
func (org *User) LoadTeams() error { | |||||
return org.loadTeams(x) | |||||
} | } | ||||
// GetMembers returns all members of organization. | // GetMembers returns all members of organization. | ||||
} | } | ||||
// CountOrgMembers counts the organization's members | // CountOrgMembers counts the organization's members | ||||
func CountOrgMembers(opts FindOrgMembersOpts) (int64, error) { | |||||
func CountOrgMembers(opts *FindOrgMembersOpts) (int64, error) { | |||||
sess := x.Where("org_id=?", opts.OrgID) | sess := x.Where("org_id=?", opts.OrgID) | ||||
if opts.PublicOnly { | if opts.PublicOnly { | ||||
sess.And("is_public = ?", true) | sess.And("is_public = ?", true) |
return getTeamMembers(x, teamID) | return getTeamMembers(x, teamID) | ||||
} | } | ||||
func getUserTeams(e Engine, userID int64, listOptions ListOptions) (teams []*Team, err error) { | |||||
sess := e. | |||||
Join("INNER", "team_user", "team_user.team_id = team.id"). | |||||
Where("team_user.uid=?", userID) | |||||
if listOptions.Page != 0 { | |||||
sess = listOptions.setSessionPagination(sess) | |||||
} | |||||
return teams, sess.Find(&teams) | |||||
} | |||||
func getUserOrgTeams(e Engine, orgID, userID int64) (teams []*Team, err error) { | func getUserOrgTeams(e Engine, orgID, userID int64) (teams []*Team, err error) { | ||||
return teams, e. | return teams, e. | ||||
Join("INNER", "team_user", "team_user.team_id = team.id"). | Join("INNER", "team_user", "team_user.team_id = team.id"). | ||||
return getUserOrgTeams(x, orgID, userID) | return getUserOrgTeams(x, orgID, userID) | ||||
} | } | ||||
// GetUserTeams returns all teams that user belongs across all organizations. | |||||
func GetUserTeams(userID int64, listOptions ListOptions) ([]*Team, error) { | |||||
return getUserTeams(x, userID, listOptions) | |||||
} | |||||
// AddTeamMember adds new membership of given team to given organization, | // AddTeamMember adds new membership of given team to given organization, | ||||
// the user will have membership to given organization automatically when needed. | // the user will have membership to given organization automatically when needed. | ||||
func AddTeamMember(team *Team, userID int64) error { | func AddTeamMember(team *Team, userID int64) error { |
func TestGetUserTeams(t *testing.T) { | func TestGetUserTeams(t *testing.T) { | ||||
assert.NoError(t, PrepareTestDatabase()) | assert.NoError(t, PrepareTestDatabase()) | ||||
test := func(userID int64) { | test := func(userID int64) { | ||||
teams, err := GetUserTeams(userID, ListOptions{}) | |||||
teams, _, err := SearchTeam(&SearchTeamOptions{UserID: userID}) | |||||
assert.NoError(t, err) | assert.NoError(t, err) | ||||
for _, team := range teams { | for _, team := range teams { | ||||
AssertExistsAndLoadBean(t, &TeamUser{TeamID: team.ID, UID: userID}) | AssertExistsAndLoadBean(t, &TeamUser{TeamID: team.ID, UID: userID}) |
func TestUser_GetTeams(t *testing.T) { | func TestUser_GetTeams(t *testing.T) { | ||||
assert.NoError(t, PrepareTestDatabase()) | assert.NoError(t, PrepareTestDatabase()) | ||||
org := AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) | org := AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) | ||||
assert.NoError(t, org.GetTeams(&SearchTeamOptions{})) | |||||
assert.NoError(t, org.LoadTeams()) | |||||
if assert.Len(t, org.Teams, 4) { | if assert.Len(t, org.Teams, 4) { | ||||
assert.Equal(t, int64(1), org.Teams[0].ID) | assert.Equal(t, int64(1), org.Teams[0].ID) | ||||
assert.Equal(t, int64(2), org.Teams[1].ID) | assert.Equal(t, int64(2), org.Teams[1].ID) |
// Give access to all members in teams with access to all repositories. | // Give access to all members in teams with access to all repositories. | ||||
if u.IsOrganization() { | if u.IsOrganization() { | ||||
if err := u.getTeams(ctx.e); err != nil { | |||||
return fmt.Errorf("GetTeams: %v", err) | |||||
if err := u.loadTeams(ctx.e); err != nil { | |||||
return fmt.Errorf("loadTeams: %v", err) | |||||
} | } | ||||
for _, t := range u.Teams { | for _, t := range u.Teams { | ||||
if t.IncludesAllRepositories { | if t.IncludesAllRepositories { | ||||
return err | return err | ||||
} | } | ||||
if org.IsOrganization() { | if org.IsOrganization() { | ||||
if err = org.getTeams(sess); err != nil { | |||||
if err = org.loadTeams(sess); err != nil { | |||||
return err | return err | ||||
} | } | ||||
} | } | ||||
} | } | ||||
// Delete Deploy Keys | // Delete Deploy Keys | ||||
deployKeys, err := listDeployKeys(sess, repo.ID, ListOptions{}) | |||||
deployKeys, err := listDeployKeys(sess, &ListDeployKeysOptions{RepoID: repoID}) | |||||
if err != nil { | if err != nil { | ||||
return fmt.Errorf("listDeployKeys: %v", err) | return fmt.Errorf("listDeployKeys: %v", err) | ||||
} | } |
return repo.getCollaborators(x, listOptions) | return repo.getCollaborators(x, listOptions) | ||||
} | } | ||||
// CountCollaborators returns total number of collaborators for a repository | |||||
func (repo *Repository) CountCollaborators() (int64, error) { | |||||
return x.Where("repo_id = ? ", repo.ID).Count(&Collaboration{}) | |||||
} | |||||
func (repo *Repository) getCollaboration(e Engine, uid int64) (*Collaboration, error) { | func (repo *Repository) getCollaboration(e Engine, uid int64) (*Collaboration, error) { | ||||
collaboration := &Collaboration{ | collaboration := &Collaboration{ | ||||
RepoID: repo.ID, | RepoID: repo.ID, |
// GenerateWebhooks generates webhooks from a template repository | // GenerateWebhooks generates webhooks from a template repository | ||||
func GenerateWebhooks(ctx DBContext, templateRepo, generateRepo *Repository) error { | func GenerateWebhooks(ctx DBContext, templateRepo, generateRepo *Repository) error { | ||||
templateWebhooks, err := GetWebhooksByRepoID(templateRepo.ID, ListOptions{}) | |||||
templateWebhooks, err := ListWebhooksByOpts(&ListWebhookOptions{RepoID: templateRepo.ID}) | |||||
if err != nil { | if err != nil { | ||||
return err | return err | ||||
} | } |
} | } | ||||
if newOwner.IsOrganization() { | if newOwner.IsOrganization() { | ||||
if err := newOwner.getTeams(sess); err != nil { | |||||
return fmt.Errorf("GetTeams: %v", err) | |||||
if err := newOwner.loadTeams(sess); err != nil { | |||||
return fmt.Errorf("LoadTeams: %v", err) | |||||
} | } | ||||
for _, t := range newOwner.Teams { | for _, t := range newOwner.Teams { | ||||
if t.IncludesAllRepositories { | if t.IncludesAllRepositories { |
return findReviews(x, opts) | return findReviews(x, opts) | ||||
} | } | ||||
// CountReviews returns count of reviews passing FindReviewOptions | |||||
func CountReviews(opts FindReviewOptions) (int64, error) { | |||||
return x.Where(opts.toCond()).Count(&Review{}) | |||||
} | |||||
// CreateReviewOptions represent the options to create a review. Type, Issue and Reviewer are required. | // CreateReviewOptions represent the options to create a review. Type, Issue and Reviewer are required. | ||||
type CreateReviewOptions struct { | type CreateReviewOptions struct { | ||||
Content string | Content string |
return keys, sess.Find(&keys) | return keys, sess.Find(&keys) | ||||
} | } | ||||
// CountPublicKeys count public keys a user has | |||||
func CountPublicKeys(userID int64) (int64, error) { | |||||
sess := x.Where("owner_id = ? AND type != ?", userID, KeyTypePrincipal) | |||||
return sess.Count(&PublicKey{}) | |||||
} | |||||
// ListPublicKeysBySource returns a list of synchronized public keys for a given user and login source. | // ListPublicKeysBySource returns a list of synchronized public keys for a given user and login source. | ||||
func ListPublicKeysBySource(uid, loginSourceID int64) ([]*PublicKey, error) { | func ListPublicKeysBySource(uid, loginSourceID int64) ([]*PublicKey, error) { | ||||
keys := make([]*PublicKey, 0, 5) | keys := make([]*PublicKey, 0, 5) |
return nil | return nil | ||||
} | } | ||||
// ListDeployKeys returns all deploy keys by given repository ID. | |||||
func ListDeployKeys(repoID int64, listOptions ListOptions) ([]*DeployKey, error) { | |||||
return listDeployKeys(x, repoID, listOptions) | |||||
// ListDeployKeysOptions are options for ListDeployKeys | |||||
type ListDeployKeysOptions struct { | |||||
ListOptions | |||||
RepoID int64 | |||||
KeyID int64 | |||||
Fingerprint string | |||||
} | |||||
func (opt ListDeployKeysOptions) toCond() builder.Cond { | |||||
cond := builder.NewCond() | |||||
if opt.RepoID != 0 { | |||||
cond = cond.And(builder.Eq{"repo_id": opt.RepoID}) | |||||
} | |||||
if opt.KeyID != 0 { | |||||
cond = cond.And(builder.Eq{"key_id": opt.KeyID}) | |||||
} | |||||
if opt.Fingerprint != "" { | |||||
cond = cond.And(builder.Eq{"fingerprint": opt.Fingerprint}) | |||||
} | |||||
return cond | |||||
} | } | ||||
func listDeployKeys(e Engine, repoID int64, listOptions ListOptions) ([]*DeployKey, error) { | |||||
sess := e.Where("repo_id = ?", repoID) | |||||
if listOptions.Page != 0 { | |||||
sess = listOptions.setSessionPagination(sess) | |||||
// ListDeployKeys returns a list of deploy keys matching the provided arguments. | |||||
func ListDeployKeys(opts *ListDeployKeysOptions) ([]*DeployKey, error) { | |||||
return listDeployKeys(x, opts) | |||||
} | |||||
keys := make([]*DeployKey, 0, listOptions.PageSize) | |||||
func listDeployKeys(e Engine, opts *ListDeployKeysOptions) ([]*DeployKey, error) { | |||||
sess := e.Where(opts.toCond()) | |||||
if opts.Page != 0 { | |||||
sess = opts.setSessionPagination(sess) | |||||
keys := make([]*DeployKey, 0, opts.PageSize) | |||||
return keys, sess.Find(&keys) | return keys, sess.Find(&keys) | ||||
} | } | ||||
return keys, sess.Find(&keys) | return keys, sess.Find(&keys) | ||||
} | } | ||||
// SearchDeployKeys returns a list of deploy keys matching the provided arguments. | |||||
func SearchDeployKeys(repoID, keyID int64, fingerprint string) ([]*DeployKey, error) { | |||||
keys := make([]*DeployKey, 0, 5) | |||||
cond := builder.NewCond() | |||||
if repoID != 0 { | |||||
cond = cond.And(builder.Eq{"repo_id": repoID}) | |||||
} | |||||
if keyID != 0 { | |||||
cond = cond.And(builder.Eq{"key_id": keyID}) | |||||
} | |||||
if fingerprint != "" { | |||||
cond = cond.And(builder.Eq{"fingerprint": fingerprint}) | |||||
} | |||||
return keys, x.Where(cond).Find(&keys) | |||||
// CountDeployKeys returns count deploy keys matching the provided arguments. | |||||
func CountDeployKeys(opts *ListDeployKeysOptions) (int64, error) { | |||||
return x.Where(opts.toCond()).Count(&DeployKey{}) | |||||
} | } |
return err | return err | ||||
} | } | ||||
// CountAccessTokens count access tokens belongs to given user by options | |||||
func CountAccessTokens(opts ListAccessTokensOptions) (int64, error) { | |||||
sess := x.Where("uid=?", opts.UserID) | |||||
if len(opts.Name) != 0 { | |||||
sess = sess.Where("name=?", opts.Name) | |||||
} | |||||
return sess.Count(&AccessToken{}) | |||||
} | |||||
// DeleteAccessTokenByID deletes access token by given ID. | // DeleteAccessTokenByID deletes access token by given ID. | ||||
func DeleteAccessTokenByID(id, userID int64) error { | func DeleteAccessTokenByID(id, userID int64) error { | ||||
cnt, err := x.ID(id).Delete(&AccessToken{ | cnt, err := x.ID(id).Delete(&AccessToken{ |
} | } | ||||
// FindTopics retrieves the topics via FindTopicOptions | // FindTopics retrieves the topics via FindTopicOptions | ||||
func FindTopics(opts *FindTopicOptions) (topics []*Topic, err error) { | |||||
func FindTopics(opts *FindTopicOptions) ([]*Topic, int64, error) { | |||||
sess := x.Select("topic.*").Where(opts.toConds()) | sess := x.Select("topic.*").Where(opts.toConds()) | ||||
if opts.RepoID > 0 { | if opts.RepoID > 0 { | ||||
sess.Join("INNER", "repo_topic", "repo_topic.topic_id = topic.id") | sess.Join("INNER", "repo_topic", "repo_topic.topic_id = topic.id") | ||||
if opts.PageSize != 0 && opts.Page != 0 { | if opts.PageSize != 0 && opts.Page != 0 { | ||||
sess = opts.setSessionPagination(sess) | sess = opts.setSessionPagination(sess) | ||||
} | } | ||||
return topics, sess.Desc("topic.repo_count").Find(&topics) | |||||
topics := make([]*Topic, 0, 10) | |||||
total, err := sess.Desc("topic.repo_count").FindAndCount(&topics) | |||||
return topics, total, err | |||||
} | |||||
// CountTopics counts the number of topics matching the FindTopicOptions | |||||
func CountTopics(opts *FindTopicOptions) (int64, error) { | |||||
sess := x.Where(opts.toConds()) | |||||
if opts.RepoID > 0 { | |||||
sess.Join("INNER", "repo_topic", "repo_topic.topic_id = topic.id") | |||||
} | |||||
return sess.Count(new(Topic)) | |||||
} | } | ||||
// GetRepoTopicByName retrieves topic from name for a repo if it exist | // GetRepoTopicByName retrieves topic from name for a repo if it exist | ||||
// SaveTopics save topics to a repository | // SaveTopics save topics to a repository | ||||
func SaveTopics(repoID int64, topicNames ...string) error { | func SaveTopics(repoID int64, topicNames ...string) error { | ||||
topics, err := FindTopics(&FindTopicOptions{ | |||||
topics, _, err := FindTopics(&FindTopicOptions{ | |||||
RepoID: repoID, | RepoID: repoID, | ||||
}) | }) | ||||
if err != nil { | if err != nil { |
assert.NoError(t, PrepareTestDatabase()) | assert.NoError(t, PrepareTestDatabase()) | ||||
topics, err := FindTopics(&FindTopicOptions{}) | |||||
topics, _, err := FindTopics(&FindTopicOptions{}) | |||||
assert.NoError(t, err) | assert.NoError(t, err) | ||||
assert.Len(t, topics, totalNrOfTopics) | assert.Len(t, topics, totalNrOfTopics) | ||||
topics, err = FindTopics(&FindTopicOptions{ | |||||
topics, total, err := FindTopics(&FindTopicOptions{ | |||||
ListOptions: ListOptions{Page: 1, PageSize: 2}, | ListOptions: ListOptions{Page: 1, PageSize: 2}, | ||||
}) | }) | ||||
assert.NoError(t, err) | assert.NoError(t, err) | ||||
assert.Len(t, topics, 2) | assert.Len(t, topics, 2) | ||||
assert.EqualValues(t, 6, total) | |||||
topics, err = FindTopics(&FindTopicOptions{ | |||||
topics, _, err = FindTopics(&FindTopicOptions{ | |||||
RepoID: 1, | RepoID: 1, | ||||
}) | }) | ||||
assert.NoError(t, err) | assert.NoError(t, err) | ||||
assert.NoError(t, SaveTopics(2, "golang")) | assert.NoError(t, SaveTopics(2, "golang")) | ||||
repo2NrOfTopics = 1 | repo2NrOfTopics = 1 | ||||
topics, err = FindTopics(&FindTopicOptions{}) | |||||
topics, _, err = FindTopics(&FindTopicOptions{}) | |||||
assert.NoError(t, err) | assert.NoError(t, err) | ||||
assert.Len(t, topics, totalNrOfTopics) | assert.Len(t, topics, totalNrOfTopics) | ||||
topics, err = FindTopics(&FindTopicOptions{ | |||||
topics, _, err = FindTopics(&FindTopicOptions{ | |||||
RepoID: 2, | RepoID: 2, | ||||
}) | }) | ||||
assert.NoError(t, err) | assert.NoError(t, err) | ||||
assert.NoError(t, err) | assert.NoError(t, err) | ||||
assert.EqualValues(t, 1, topic.RepoCount) | assert.EqualValues(t, 1, topic.RepoCount) | ||||
topics, err = FindTopics(&FindTopicOptions{}) | |||||
topics, _, err = FindTopics(&FindTopicOptions{}) | |||||
assert.NoError(t, err) | assert.NoError(t, err) | ||||
assert.Len(t, topics, totalNrOfTopics) | assert.Len(t, topics, totalNrOfTopics) | ||||
topics, err = FindTopics(&FindTopicOptions{ | |||||
topics, _, err = FindTopics(&FindTopicOptions{ | |||||
RepoID: 2, | RepoID: 2, | ||||
}) | }) | ||||
assert.NoError(t, err) | assert.NoError(t, err) |
} | } | ||||
// GetWatchedRepos returns the repos watched by a particular user | // GetWatchedRepos returns the repos watched by a particular user | ||||
func GetWatchedRepos(userID int64, private bool, listOptions ListOptions) ([]*Repository, error) { | |||||
func GetWatchedRepos(userID int64, private bool, listOptions ListOptions) ([]*Repository, int64, error) { | |||||
sess := x.Where("watch.user_id=?", userID). | sess := x.Where("watch.user_id=?", userID). | ||||
And("`watch`.mode<>?", RepoWatchModeDont). | And("`watch`.mode<>?", RepoWatchModeDont). | ||||
Join("LEFT", "watch", "`repository`.id=`watch`.repo_id") | Join("LEFT", "watch", "`repository`.id=`watch`.repo_id") | ||||
sess = listOptions.setSessionPagination(sess) | sess = listOptions.setSessionPagination(sess) | ||||
repos := make([]*Repository, 0, listOptions.PageSize) | repos := make([]*Repository, 0, listOptions.PageSize) | ||||
return repos, sess.Find(&repos) | |||||
total, err := sess.FindAndCount(&repos) | |||||
return repos, total, err | |||||
} | } | ||||
repos := make([]*Repository, 0, 10) | repos := make([]*Repository, 0, 10) | ||||
return repos, sess.Find(&repos) | |||||
total, err := sess.FindAndCount(&repos) | |||||
return repos, total, err | |||||
} | } | ||||
// IterateUser iterate users | // IterateUser iterate users |
"code.gitea.io/gitea/modules/setting" | "code.gitea.io/gitea/modules/setting" | ||||
api "code.gitea.io/gitea/modules/structs" | api "code.gitea.io/gitea/modules/structs" | ||||
"code.gitea.io/gitea/modules/timeutil" | "code.gitea.io/gitea/modules/timeutil" | ||||
"code.gitea.io/gitea/modules/util" | |||||
gouuid "github.com/google/uuid" | gouuid "github.com/google/uuid" | ||||
"xorm.io/builder" | |||||
) | ) | ||||
// HookContentType is the content type of a web hook | // HookContentType is the content type of a web hook | ||||
}) | }) | ||||
} | } | ||||
// GetActiveWebhooksByRepoID returns all active webhooks of repository. | |||||
func GetActiveWebhooksByRepoID(repoID int64) ([]*Webhook, error) { | |||||
return getActiveWebhooksByRepoID(x, repoID) | |||||
// ListWebhookOptions are options to filter webhooks on ListWebhooksByOpts | |||||
type ListWebhookOptions struct { | |||||
ListOptions | |||||
RepoID int64 | |||||
OrgID int64 | |||||
IsActive util.OptionalBool | |||||
} | } | ||||
func getActiveWebhooksByRepoID(e Engine, repoID int64) ([]*Webhook, error) { | |||||
webhooks := make([]*Webhook, 0, 5) | |||||
return webhooks, e.Where("is_active=?", true). | |||||
Find(&webhooks, &Webhook{RepoID: repoID}) | |||||
} | |||||
// GetWebhooksByRepoID returns all webhooks of a repository. | |||||
func GetWebhooksByRepoID(repoID int64, listOptions ListOptions) ([]*Webhook, error) { | |||||
if listOptions.Page == 0 { | |||||
webhooks := make([]*Webhook, 0, 5) | |||||
return webhooks, x.Find(&webhooks, &Webhook{RepoID: repoID}) | |||||
func (opts *ListWebhookOptions) toCond() builder.Cond { | |||||
cond := builder.NewCond() | |||||
if opts.RepoID != 0 { | |||||
cond = cond.And(builder.Eq{"webhook.repo_id": opts.RepoID}) | |||||
} | |||||
if opts.OrgID != 0 { | |||||
cond = cond.And(builder.Eq{"webhook.org_id": opts.OrgID}) | |||||
} | |||||
if !opts.IsActive.IsNone() { | |||||
cond = cond.And(builder.Eq{"webhook.is_active": opts.IsActive.IsTrue()}) | |||||
} | } | ||||
return cond | |||||
} | |||||
sess := listOptions.getPaginatedSession() | |||||
webhooks := make([]*Webhook, 0, listOptions.PageSize) | |||||
func listWebhooksByOpts(e Engine, opts *ListWebhookOptions) ([]*Webhook, error) { | |||||
sess := e.Where(opts.toCond()) | |||||
return webhooks, sess.Find(&webhooks, &Webhook{RepoID: repoID}) | |||||
} | |||||
if opts.Page != 0 { | |||||
sess = opts.setSessionPagination(sess) | |||||
webhooks := make([]*Webhook, 0, opts.PageSize) | |||||
err := sess.Find(&webhooks) | |||||
return webhooks, err | |||||
} | |||||
// GetActiveWebhooksByOrgID returns all active webhooks for an organization. | |||||
func GetActiveWebhooksByOrgID(orgID int64) (ws []*Webhook, err error) { | |||||
return getActiveWebhooksByOrgID(x, orgID) | |||||
webhooks := make([]*Webhook, 0, 10) | |||||
err := sess.Find(&webhooks) | |||||
return webhooks, err | |||||
} | } | ||||
func getActiveWebhooksByOrgID(e Engine, orgID int64) (ws []*Webhook, err error) { | |||||
err = e. | |||||
Where("org_id=?", orgID). | |||||
And("is_active=?", true). | |||||
Find(&ws) | |||||
return ws, err | |||||
// ListWebhooksByOpts return webhooks based on options | |||||
func ListWebhooksByOpts(opts *ListWebhookOptions) ([]*Webhook, error) { | |||||
return listWebhooksByOpts(x, opts) | |||||
} | } | ||||
// GetWebhooksByOrgID returns paginated webhooks for an organization. | |||||
func GetWebhooksByOrgID(orgID int64, listOptions ListOptions) ([]*Webhook, error) { | |||||
if listOptions.Page == 0 { | |||||
ws := make([]*Webhook, 0, 5) | |||||
return ws, x.Find(&ws, &Webhook{OrgID: orgID}) | |||||
} | |||||
sess := listOptions.getPaginatedSession() | |||||
ws := make([]*Webhook, 0, listOptions.PageSize) | |||||
return ws, sess.Find(&ws, &Webhook{OrgID: orgID}) | |||||
// CountWebhooksByOpts count webhooks based on options and ignore pagination | |||||
func CountWebhooksByOpts(opts *ListWebhookOptions) (int64, error) { | |||||
return x.Where(opts.toCond()).Count(&Webhook{}) | |||||
} | } | ||||
// GetDefaultWebhooks returns all admin-default webhooks. | // GetDefaultWebhooks returns all admin-default webhooks. |
"code.gitea.io/gitea/modules/json" | "code.gitea.io/gitea/modules/json" | ||||
api "code.gitea.io/gitea/modules/structs" | api "code.gitea.io/gitea/modules/structs" | ||||
"code.gitea.io/gitea/modules/util" | |||||
"github.com/stretchr/testify/assert" | "github.com/stretchr/testify/assert" | ||||
) | ) | ||||
func TestGetActiveWebhooksByRepoID(t *testing.T) { | func TestGetActiveWebhooksByRepoID(t *testing.T) { | ||||
assert.NoError(t, PrepareTestDatabase()) | assert.NoError(t, PrepareTestDatabase()) | ||||
hooks, err := GetActiveWebhooksByRepoID(1) | |||||
hooks, err := ListWebhooksByOpts(&ListWebhookOptions{RepoID: 1, IsActive: util.OptionalBoolTrue}) | |||||
assert.NoError(t, err) | assert.NoError(t, err) | ||||
if assert.Len(t, hooks, 1) { | if assert.Len(t, hooks, 1) { | ||||
assert.Equal(t, int64(1), hooks[0].ID) | assert.Equal(t, int64(1), hooks[0].ID) | ||||
func TestGetWebhooksByRepoID(t *testing.T) { | func TestGetWebhooksByRepoID(t *testing.T) { | ||||
assert.NoError(t, PrepareTestDatabase()) | assert.NoError(t, PrepareTestDatabase()) | ||||
hooks, err := GetWebhooksByRepoID(1, ListOptions{}) | |||||
hooks, err := ListWebhooksByOpts(&ListWebhookOptions{RepoID: 1}) | |||||
assert.NoError(t, err) | assert.NoError(t, err) | ||||
if assert.Len(t, hooks, 2) { | if assert.Len(t, hooks, 2) { | ||||
assert.Equal(t, int64(1), hooks[0].ID) | assert.Equal(t, int64(1), hooks[0].ID) | ||||
func TestGetActiveWebhooksByOrgID(t *testing.T) { | func TestGetActiveWebhooksByOrgID(t *testing.T) { | ||||
assert.NoError(t, PrepareTestDatabase()) | assert.NoError(t, PrepareTestDatabase()) | ||||
hooks, err := GetActiveWebhooksByOrgID(3) | |||||
hooks, err := ListWebhooksByOpts(&ListWebhookOptions{OrgID: 3, IsActive: util.OptionalBoolTrue}) | |||||
assert.NoError(t, err) | assert.NoError(t, err) | ||||
if assert.Len(t, hooks, 1) { | if assert.Len(t, hooks, 1) { | ||||
assert.Equal(t, int64(3), hooks[0].ID) | assert.Equal(t, int64(3), hooks[0].ID) | ||||
func TestGetWebhooksByOrgID(t *testing.T) { | func TestGetWebhooksByOrgID(t *testing.T) { | ||||
assert.NoError(t, PrepareTestDatabase()) | assert.NoError(t, PrepareTestDatabase()) | ||||
hooks, err := GetWebhooksByOrgID(3, ListOptions{}) | |||||
hooks, err := ListWebhooksByOpts(&ListWebhookOptions{OrgID: 3}) | |||||
assert.NoError(t, err) | assert.NoError(t, err) | ||||
if assert.Len(t, hooks, 1) { | if assert.Len(t, hooks, 1) { | ||||
assert.Equal(t, int64(3), hooks[0].ID) | assert.Equal(t, int64(3), hooks[0].ID) |
if len(links) > 0 { | if len(links) > 0 { | ||||
ctx.Header().Set("Link", strings.Join(links, ",")) | ctx.Header().Set("Link", strings.Join(links, ",")) | ||||
ctx.AppendAccessControlExposeHeaders("Link") | |||||
} | |||||
} | |||||
// SetTotalCountHeader set "X-Total-Count" header | |||||
func (ctx *APIContext) SetTotalCountHeader(total int64) { | |||||
ctx.Header().Set("X-Total-Count", fmt.Sprint(total)) | |||||
ctx.AppendAccessControlExposeHeaders("X-Total-Count") | |||||
} | |||||
// AppendAccessControlExposeHeaders append headers by name to "Access-Control-Expose-Headers" header | |||||
func (ctx *APIContext) AppendAccessControlExposeHeaders(names ...string) { | |||||
val := ctx.Header().Get("Access-Control-Expose-Headers") | |||||
if len(val) != 0 { | |||||
ctx.Header().Set("Access-Control-Expose-Headers", fmt.Sprintf("%s, %s", val, strings.Join(names, ", "))) | |||||
} else { | |||||
ctx.Header().Set("Access-Control-Expose-Headers", strings.Join(names, ", ")) | |||||
} | } | ||||
} | } | ||||
// Team. | // Team. | ||||
if ctx.Org.IsMember { | if ctx.Org.IsMember { | ||||
if ctx.Org.IsOwner { | if ctx.Org.IsOwner { | ||||
if err := org.GetTeams(&models.SearchTeamOptions{}); err != nil { | |||||
ctx.ServerError("GetTeams", err) | |||||
if err := org.LoadTeams(); err != nil { | |||||
ctx.ServerError("LoadTeams", err) | |||||
return | return | ||||
} | } | ||||
} else { | } else { |
"strings" | "strings" | ||||
"code.gitea.io/gitea/modules/log" | "code.gitea.io/gitea/modules/log" | ||||
"code.gitea.io/gitea/modules/util" | |||||
) | ) | ||||
// TagPrefix tags prefix path on the repository | // TagPrefix tags prefix path on the repository | ||||
} | } | ||||
// GetTagInfos returns all tag infos of the repository. | // GetTagInfos returns all tag infos of the repository. | ||||
func (repo *Repository) GetTagInfos(page, pageSize int) ([]*Tag, error) { | |||||
func (repo *Repository) GetTagInfos(page, pageSize int) ([]*Tag, int, error) { | |||||
// TODO this a slow implementation, makes one git command per tag | // TODO this a slow implementation, makes one git command per tag | ||||
stdout, err := NewCommand("tag").RunInDir(repo.Path) | stdout, err := NewCommand("tag").RunInDir(repo.Path) | ||||
if err != nil { | if err != nil { | ||||
return nil, err | |||||
return nil, 0, err | |||||
} | } | ||||
tagNames := strings.Split(strings.TrimRight(stdout, "\n"), "\n") | tagNames := strings.Split(strings.TrimRight(stdout, "\n"), "\n") | ||||
tagsTotal := len(tagNames) | |||||
if page != 0 { | if page != 0 { | ||||
skip := (page - 1) * pageSize | |||||
if skip >= len(tagNames) { | |||||
return nil, nil | |||||
} | |||||
if (len(tagNames) - skip) < pageSize { | |||||
pageSize = len(tagNames) - skip | |||||
} | |||||
tagNames = tagNames[skip : skip+pageSize] | |||||
tagNames = util.PaginateSlice(tagNames, page, pageSize).([]string) | |||||
} | } | ||||
var tags = make([]*Tag, 0, len(tagNames)) | var tags = make([]*Tag, 0, len(tagNames)) | ||||
tag, err := repo.GetTag(tagName) | tag, err := repo.GetTag(tagName) | ||||
if err != nil { | if err != nil { | ||||
return nil, err | |||||
return nil, tagsTotal, err | |||||
} | } | ||||
tag.Name = tagName | tag.Name = tagName | ||||
tags = append(tags, tag) | tags = append(tags, tag) | ||||
} | } | ||||
sortTagsByTime(tags) | sortTagsByTime(tags) | ||||
return tags, nil | |||||
return tags, tagsTotal, nil | |||||
} | } | ||||
// GetTagType gets the type of the tag, either commit (simple) or tag (annotated) | // GetTagType gets the type of the tag, either commit (simple) or tag (annotated) |
assert.NoError(t, err) | assert.NoError(t, err) | ||||
defer bareRepo1.Close() | defer bareRepo1.Close() | ||||
tags, err := bareRepo1.GetTagInfos(0, 0) | |||||
tags, total, err := bareRepo1.GetTagInfos(0, 0) | |||||
assert.NoError(t, err) | assert.NoError(t, err) | ||||
assert.Len(t, tags, 1) | assert.Len(t, tags, 1) | ||||
assert.Equal(t, len(tags), total) | |||||
assert.EqualValues(t, "test", tags[0].Name) | assert.EqualValues(t, "test", tags[0].Name) | ||||
assert.EqualValues(t, "3ad28a9149a2864384548f3d17ed7f38014c9e8a", tags[0].ID.String()) | assert.EqualValues(t, "3ad28a9149a2864384548f3d17ed7f38014c9e8a", tags[0].ID.String()) | ||||
assert.EqualValues(t, "tag", tags[0].Type) | assert.EqualValues(t, "tag", tags[0].Type) |
assert.True(t, repo.HasWiki()) | assert.True(t, repo.HasWiki()) | ||||
assert.EqualValues(t, models.RepositoryReady, repo.Status) | assert.EqualValues(t, models.RepositoryReady, repo.Status) | ||||
milestones, err := models.GetMilestones(models.GetMilestonesOption{ | |||||
milestones, _, err := models.GetMilestones(models.GetMilestonesOption{ | |||||
RepoID: repo.ID, | RepoID: repo.ID, | ||||
State: structs.StateOpen, | State: structs.StateOpen, | ||||
}) | }) | ||||
assert.NoError(t, err) | assert.NoError(t, err) | ||||
assert.Len(t, milestones, 1) | assert.Len(t, milestones, 1) | ||||
milestones, err = models.GetMilestones(models.GetMilestonesOption{ | |||||
milestones, _, err = models.GetMilestones(models.GetMilestonesOption{ | |||||
RepoID: repo.ID, | RepoID: repo.ID, | ||||
State: structs.StateClosed, | State: structs.StateClosed, | ||||
}) | }) |
package admin | package admin | ||||
import ( | import ( | ||||
"fmt" | |||||
"net/http" | "net/http" | ||||
"code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
ctx.InternalServerError(err) | ctx.InternalServerError(err) | ||||
} | } | ||||
ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", count)) | |||||
ctx.Header().Set("Access-Control-Expose-Headers", "X-Total-Count") | |||||
ctx.SetTotalCountHeader(int64(count)) | |||||
ctx.JSON(http.StatusOK, repoNames) | ctx.JSON(http.StatusOK, repoNames) | ||||
} | } |
"code.gitea.io/gitea/modules/cron" | "code.gitea.io/gitea/modules/cron" | ||||
"code.gitea.io/gitea/modules/log" | "code.gitea.io/gitea/modules/log" | ||||
"code.gitea.io/gitea/modules/structs" | "code.gitea.io/gitea/modules/structs" | ||||
"code.gitea.io/gitea/modules/util" | |||||
"code.gitea.io/gitea/routers/api/v1/utils" | "code.gitea.io/gitea/routers/api/v1/utils" | ||||
) | ) | ||||
// "403": | // "403": | ||||
// "$ref": "#/responses/forbidden" | // "$ref": "#/responses/forbidden" | ||||
tasks := cron.ListTasks() | tasks := cron.ListTasks() | ||||
listOpts := utils.GetListOptions(ctx) | |||||
start, end := listOpts.GetStartEnd() | |||||
count := len(tasks) | |||||
if len(tasks) > listOpts.PageSize { | |||||
tasks = tasks[start:end] | |||||
} | |||||
listOpts := utils.GetListOptions(ctx) | |||||
tasks = util.PaginateSlice(tasks, listOpts.Page, listOpts.PageSize).(cron.TaskTable) | |||||
res := make([]structs.Cron, len(tasks)) | res := make([]structs.Cron, len(tasks)) | ||||
for i, task := range tasks { | for i, task := range tasks { | ||||
ExecTimes: task.ExecTimes, | ExecTimes: task.ExecTimes, | ||||
} | } | ||||
} | } | ||||
ctx.SetTotalCountHeader(int64(count)) | |||||
ctx.JSON(http.StatusOK, res) | ctx.JSON(http.StatusOK, res) | ||||
} | } | ||||
package admin | package admin | ||||
import ( | import ( | ||||
"fmt" | |||||
"net/http" | "net/http" | ||||
"code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
} | } | ||||
ctx.SetLinkHeader(int(maxResults), listOptions.PageSize) | ctx.SetLinkHeader(int(maxResults), listOptions.PageSize) | ||||
ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", maxResults)) | |||||
ctx.Header().Set("Access-Control-Expose-Headers", "X-Total-Count, Link") | |||||
ctx.SetTotalCountHeader(maxResults) | |||||
ctx.JSON(http.StatusOK, &orgs) | ctx.JSON(http.StatusOK, &orgs) | ||||
} | } |
} | } | ||||
ctx.SetLinkHeader(int(maxResults), listOptions.PageSize) | ctx.SetLinkHeader(int(maxResults), listOptions.PageSize) | ||||
ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", maxResults)) | |||||
ctx.Header().Set("Access-Control-Expose-Headers", "X-Total-Count, Link") | |||||
ctx.SetTotalCountHeader(maxResults) | |||||
ctx.JSON(http.StatusOK, &results) | ctx.JSON(http.StatusOK, &results) | ||||
} | } |
} | } | ||||
opts.RepoID = ctx.Repo.Repository.ID | opts.RepoID = ctx.Repo.Repository.ID | ||||
totalCount, err := models.CountNotifications(opts) | |||||
if err != nil { | |||||
ctx.InternalServerError(err) | |||||
return | |||||
} | |||||
nl, err := models.GetNotifications(opts) | nl, err := models.GetNotifications(opts) | ||||
if err != nil { | if err != nil { | ||||
ctx.InternalServerError(err) | ctx.InternalServerError(err) | ||||
return | return | ||||
} | } | ||||
ctx.SetTotalCountHeader(totalCount) | |||||
ctx.JSON(http.StatusOK, convert.ToNotifications(nl)) | ctx.JSON(http.StatusOK, convert.ToNotifications(nl)) | ||||
} | } | ||||
return | return | ||||
} | } | ||||
totalCount, err := models.CountNotifications(opts) | |||||
if err != nil { | |||||
ctx.InternalServerError(err) | |||||
return | |||||
} | |||||
nl, err := models.GetNotifications(opts) | nl, err := models.GetNotifications(opts) | ||||
if err != nil { | if err != nil { | ||||
ctx.InternalServerError(err) | ctx.InternalServerError(err) | ||||
return | return | ||||
} | } | ||||
ctx.SetTotalCountHeader(totalCount) | |||||
ctx.JSON(http.StatusOK, convert.ToNotifications(nl)) | ctx.JSON(http.StatusOK, convert.ToNotifications(nl)) | ||||
} | } | ||||
// "200": | // "200": | ||||
// "$ref": "#/responses/HookList" | // "$ref": "#/responses/HookList" | ||||
org := ctx.Org.Organization | |||||
orgHooks, err := models.GetWebhooksByOrgID(org.ID, utils.GetListOptions(ctx)) | |||||
opts := &models.ListWebhookOptions{ | |||||
ListOptions: utils.GetListOptions(ctx), | |||||
OrgID: ctx.Org.Organization.ID, | |||||
} | |||||
count, err := models.CountWebhooksByOpts(opts) | |||||
if err != nil { | if err != nil { | ||||
ctx.Error(http.StatusInternalServerError, "GetWebhooksByOrgID", err) | |||||
ctx.InternalServerError(err) | |||||
return | return | ||||
} | } | ||||
orgHooks, err := models.ListWebhooksByOpts(opts) | |||||
if err != nil { | |||||
ctx.InternalServerError(err) | |||||
return | |||||
} | |||||
hooks := make([]*api.Hook, len(orgHooks)) | hooks := make([]*api.Hook, len(orgHooks)) | ||||
for i, hook := range orgHooks { | for i, hook := range orgHooks { | ||||
hooks[i] = convert.ToHook(org.HomeLink(), hook) | |||||
hooks[i] = convert.ToHook(ctx.Org.Organization.HomeLink(), hook) | |||||
} | } | ||||
ctx.SetTotalCountHeader(count) | |||||
ctx.JSON(http.StatusOK, hooks) | ctx.JSON(http.StatusOK, hooks) | ||||
} | } | ||||
return | return | ||||
} | } | ||||
count, err := models.CountLabelsByOrgID(ctx.Org.Organization.ID) | |||||
if err != nil { | |||||
ctx.InternalServerError(err) | |||||
return | |||||
} | |||||
ctx.SetTotalCountHeader(count) | |||||
ctx.JSON(http.StatusOK, convert.ToLabelList(labels)) | ctx.JSON(http.StatusOK, convert.ToLabelList(labels)) | ||||
} | } | ||||
// listMembers list an organization's members | // listMembers list an organization's members | ||||
func listMembers(ctx *context.APIContext, publicOnly bool) { | func listMembers(ctx *context.APIContext, publicOnly bool) { | ||||
var members []*models.User | |||||
members, _, err := models.FindOrgMembers(&models.FindOrgMembersOpts{ | |||||
opts := &models.FindOrgMembersOpts{ | |||||
OrgID: ctx.Org.Organization.ID, | OrgID: ctx.Org.Organization.ID, | ||||
PublicOnly: publicOnly, | PublicOnly: publicOnly, | ||||
ListOptions: utils.GetListOptions(ctx), | ListOptions: utils.GetListOptions(ctx), | ||||
}) | |||||
} | |||||
count, err := models.CountOrgMembers(opts) | |||||
if err != nil { | |||||
ctx.InternalServerError(err) | |||||
return | |||||
} | |||||
members, _, err := models.FindOrgMembers(opts) | |||||
if err != nil { | if err != nil { | ||||
ctx.Error(http.StatusInternalServerError, "GetUsersByIDs", err) | |||||
ctx.InternalServerError(err) | |||||
return | return | ||||
} | } | ||||
apiMembers[i] = convert.ToUser(member, ctx.User) | apiMembers[i] = convert.ToUser(member, ctx.User) | ||||
} | } | ||||
ctx.SetTotalCountHeader(count) | |||||
ctx.JSON(http.StatusOK, apiMembers) | ctx.JSON(http.StatusOK, apiMembers) | ||||
} | } | ||||
package org | package org | ||||
import ( | import ( | ||||
"fmt" | |||||
"net/http" | "net/http" | ||||
"code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
apiOrgs[i] = convert.ToOrganization(orgs[i]) | apiOrgs[i] = convert.ToOrganization(orgs[i]) | ||||
} | } | ||||
ctx.SetLinkHeader(int(maxResults), listOptions.PageSize) | |||||
ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", maxResults)) | |||||
ctx.Header().Set("Access-Control-Expose-Headers", "X-Total-Count, Link") | |||||
ctx.SetLinkHeader(maxResults, listOptions.PageSize) | |||||
ctx.SetTotalCountHeader(int64(maxResults)) | |||||
ctx.JSON(http.StatusOK, &apiOrgs) | ctx.JSON(http.StatusOK, &apiOrgs) | ||||
} | } | ||||
} | } | ||||
ctx.SetLinkHeader(int(maxResults), listOptions.PageSize) | ctx.SetLinkHeader(int(maxResults), listOptions.PageSize) | ||||
ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", maxResults)) | |||||
ctx.Header().Set("Access-Control-Expose-Headers", "X-Total-Count, Link") | |||||
ctx.SetTotalCountHeader(maxResults) | |||||
ctx.JSON(http.StatusOK, &orgs) | ctx.JSON(http.StatusOK, &orgs) | ||||
} | } | ||||
package org | package org | ||||
import ( | import ( | ||||
"fmt" | |||||
"net/http" | "net/http" | ||||
"code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
// "200": | // "200": | ||||
// "$ref": "#/responses/TeamList" | // "$ref": "#/responses/TeamList" | ||||
org := ctx.Org.Organization | |||||
if err := org.GetTeams(&models.SearchTeamOptions{ | |||||
teams, count, err := models.SearchTeam(&models.SearchTeamOptions{ | |||||
ListOptions: utils.GetListOptions(ctx), | ListOptions: utils.GetListOptions(ctx), | ||||
}); err != nil { | |||||
ctx.Error(http.StatusInternalServerError, "GetTeams", err) | |||||
OrgID: ctx.Org.Organization.ID, | |||||
}) | |||||
if err != nil { | |||||
ctx.Error(http.StatusInternalServerError, "LoadTeams", err) | |||||
return | return | ||||
} | } | ||||
apiTeams := make([]*api.Team, len(org.Teams)) | |||||
for i := range org.Teams { | |||||
if err := org.Teams[i].GetUnits(); err != nil { | |||||
apiTeams := make([]*api.Team, len(teams)) | |||||
for i := range teams { | |||||
if err := teams[i].GetUnits(); err != nil { | |||||
ctx.Error(http.StatusInternalServerError, "GetUnits", err) | ctx.Error(http.StatusInternalServerError, "GetUnits", err) | ||||
return | return | ||||
} | } | ||||
apiTeams[i] = convert.ToTeam(org.Teams[i]) | |||||
apiTeams[i] = convert.ToTeam(teams[i]) | |||||
} | } | ||||
ctx.SetTotalCountHeader(count) | |||||
ctx.JSON(http.StatusOK, apiTeams) | ctx.JSON(http.StatusOK, apiTeams) | ||||
} | } | ||||
// "200": | // "200": | ||||
// "$ref": "#/responses/TeamList" | // "$ref": "#/responses/TeamList" | ||||
teams, err := models.GetUserTeams(ctx.User.ID, utils.GetListOptions(ctx)) | |||||
teams, count, err := models.SearchTeam(&models.SearchTeamOptions{ | |||||
ListOptions: utils.GetListOptions(ctx), | |||||
UserID: ctx.User.ID, | |||||
}) | |||||
if err != nil { | if err != nil { | ||||
ctx.Error(http.StatusInternalServerError, "GetUserTeams", err) | ctx.Error(http.StatusInternalServerError, "GetUserTeams", err) | ||||
return | return | ||||
apiTeams[i] = convert.ToTeam(teams[i]) | apiTeams[i] = convert.ToTeam(teams[i]) | ||||
apiTeams[i].Organization = apiOrg | apiTeams[i].Organization = apiOrg | ||||
} | } | ||||
ctx.SetTotalCountHeader(count) | |||||
ctx.JSON(http.StatusOK, apiTeams) | ctx.JSON(http.StatusOK, apiTeams) | ||||
} | } | ||||
ctx.NotFound() | ctx.NotFound() | ||||
return | return | ||||
} | } | ||||
team := ctx.Org.Team | |||||
if err := team.GetMembers(&models.SearchMembersOptions{ | |||||
if err := ctx.Org.Team.GetMembers(&models.SearchMembersOptions{ | |||||
ListOptions: utils.GetListOptions(ctx), | ListOptions: utils.GetListOptions(ctx), | ||||
}); err != nil { | }); err != nil { | ||||
ctx.Error(http.StatusInternalServerError, "GetTeamMembers", err) | ctx.Error(http.StatusInternalServerError, "GetTeamMembers", err) | ||||
return | return | ||||
} | } | ||||
members := make([]*api.User, len(team.Members)) | |||||
for i, member := range team.Members { | |||||
members := make([]*api.User, len(ctx.Org.Team.Members)) | |||||
for i, member := range ctx.Org.Team.Members { | |||||
members[i] = convert.ToUser(member, ctx.User) | members[i] = convert.ToUser(member, ctx.User) | ||||
} | } | ||||
ctx.SetTotalCountHeader(int64(ctx.Org.Team.NumMembers)) | |||||
ctx.JSON(http.StatusOK, members) | ctx.JSON(http.StatusOK, members) | ||||
} | } | ||||
} | } | ||||
ctx.SetLinkHeader(int(maxResults), listOptions.PageSize) | ctx.SetLinkHeader(int(maxResults), listOptions.PageSize) | ||||
ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", maxResults)) | |||||
ctx.Header().Set("Access-Control-Expose-Headers", "X-Total-Count, Link") | |||||
ctx.SetTotalCountHeader(maxResults) | |||||
ctx.JSON(http.StatusOK, map[string]interface{}{ | ctx.JSON(http.StatusOK, map[string]interface{}{ | ||||
"ok": true, | "ok": true, | ||||
"data": apiTeams, | "data": apiTeams, |
} | } | ||||
} | } | ||||
ctx.SetLinkHeader(int(totalNumOfBranches), listOptions.PageSize) | |||||
ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", totalNumOfBranches)) | |||||
ctx.Header().Set("Access-Control-Expose-Headers", "X-Total-Count, Link") | |||||
ctx.SetLinkHeader(totalNumOfBranches, listOptions.PageSize) | |||||
ctx.SetTotalCountHeader(int64(totalNumOfBranches)) | |||||
ctx.JSON(http.StatusOK, &apiBranches) | ctx.JSON(http.StatusOK, &apiBranches) | ||||
} | } | ||||
// "200": | // "200": | ||||
// "$ref": "#/responses/UserList" | // "$ref": "#/responses/UserList" | ||||
count, err := ctx.Repo.Repository.CountCollaborators() | |||||
if err != nil { | |||||
ctx.InternalServerError(err) | |||||
return | |||||
} | |||||
collaborators, err := ctx.Repo.Repository.GetCollaborators(utils.GetListOptions(ctx)) | collaborators, err := ctx.Repo.Repository.GetCollaborators(utils.GetListOptions(ctx)) | ||||
if err != nil { | if err != nil { | ||||
ctx.Error(http.StatusInternalServerError, "ListCollaborators", err) | ctx.Error(http.StatusInternalServerError, "ListCollaborators", err) | ||||
return | return | ||||
} | } | ||||
users := make([]*api.User, len(collaborators)) | users := make([]*api.User, len(collaborators)) | ||||
for i, collaborator := range collaborators { | for i, collaborator := range collaborators { | ||||
users[i] = convert.ToUser(collaborator.User, ctx.User) | users[i] = convert.ToUser(collaborator.User, ctx.User) | ||||
} | } | ||||
ctx.SetTotalCountHeader(count) | |||||
ctx.JSON(http.StatusOK, users) | ctx.JSON(http.StatusOK, users) | ||||
} | } | ||||
} | } | ||||
} | } | ||||
ctx.SetLinkHeader(int(commitsCountTotal), listOptions.PageSize) | |||||
ctx.SetTotalCountHeader(commitsCountTotal) | |||||
// kept for backwards compatibility | // kept for backwards compatibility | ||||
ctx.Header().Set("X-Page", strconv.Itoa(listOptions.Page)) | ctx.Header().Set("X-Page", strconv.Itoa(listOptions.Page)) | ||||
ctx.Header().Set("X-PerPage", strconv.Itoa(listOptions.PageSize)) | ctx.Header().Set("X-PerPage", strconv.Itoa(listOptions.PageSize)) | ||||
ctx.Header().Set("X-Total", strconv.FormatInt(commitsCountTotal, 10)) | ctx.Header().Set("X-Total", strconv.FormatInt(commitsCountTotal, 10)) | ||||
ctx.Header().Set("X-PageCount", strconv.Itoa(pageCount)) | ctx.Header().Set("X-PageCount", strconv.Itoa(pageCount)) | ||||
ctx.Header().Set("X-HasMore", strconv.FormatBool(listOptions.Page < pageCount)) | ctx.Header().Set("X-HasMore", strconv.FormatBool(listOptions.Page < pageCount)) | ||||
ctx.SetLinkHeader(int(commitsCountTotal), listOptions.PageSize) | |||||
ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", commitsCountTotal)) | |||||
ctx.Header().Set("Access-Control-Expose-Headers", "X-Total-Count, X-PerPage, X-Total, X-PageCount, X-HasMore, Link") | |||||
ctx.AppendAccessControlExposeHeaders("X-Page", "X-PerPage", "X-Total", "X-PageCount", "X-HasMore") | |||||
ctx.JSON(http.StatusOK, &apiCommits) | ctx.JSON(http.StatusOK, &apiCommits) | ||||
} | } |
} | } | ||||
apiForks[i] = convert.ToRepo(fork, access) | apiForks[i] = convert.ToRepo(fork, access) | ||||
} | } | ||||
ctx.SetTotalCountHeader(int64(ctx.Repo.Repository.NumForks)) | |||||
ctx.JSON(http.StatusOK, apiForks) | ctx.JSON(http.StatusOK, apiForks) | ||||
} | } | ||||
// "200": | // "200": | ||||
// "$ref": "#/responses/HookList" | // "$ref": "#/responses/HookList" | ||||
hooks, err := models.GetWebhooksByRepoID(ctx.Repo.Repository.ID, utils.GetListOptions(ctx)) | |||||
opts := &models.ListWebhookOptions{ | |||||
ListOptions: utils.GetListOptions(ctx), | |||||
RepoID: ctx.Repo.Repository.ID, | |||||
} | |||||
count, err := models.CountWebhooksByOpts(opts) | |||||
if err != nil { | if err != nil { | ||||
ctx.Error(http.StatusInternalServerError, "GetWebhooksByRepoID", err) | |||||
ctx.InternalServerError(err) | |||||
return | |||||
} | |||||
hooks, err := models.ListWebhooksByOpts(opts) | |||||
if err != nil { | |||||
ctx.InternalServerError(err) | |||||
return | return | ||||
} | } | ||||
for i := range hooks { | for i := range hooks { | ||||
apiHooks[i] = convert.ToHook(ctx.Repo.RepoLink, hooks[i]) | apiHooks[i] = convert.ToHook(ctx.Repo.RepoLink, hooks[i]) | ||||
} | } | ||||
ctx.SetTotalCountHeader(count) | |||||
ctx.JSON(http.StatusOK, &apiHooks) | ctx.JSON(http.StatusOK, &apiHooks) | ||||
} | } | ||||
} | } | ||||
ctx.SetLinkHeader(int(filteredCount), setting.UI.IssuePagingNum) | ctx.SetLinkHeader(int(filteredCount), setting.UI.IssuePagingNum) | ||||
ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", filteredCount)) | |||||
ctx.Header().Set("Access-Control-Expose-Headers", "X-Total-Count, Link") | |||||
ctx.SetTotalCountHeader(filteredCount) | |||||
ctx.JSON(http.StatusOK, convert.ToAPIIssueList(issues)) | ctx.JSON(http.StatusOK, convert.ToAPIIssueList(issues)) | ||||
} | } | ||||
} | } | ||||
ctx.SetLinkHeader(int(filteredCount), listOptions.PageSize) | ctx.SetLinkHeader(int(filteredCount), listOptions.PageSize) | ||||
ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", filteredCount)) | |||||
ctx.Header().Set("Access-Control-Expose-Headers", "X-Total-Count, Link") | |||||
ctx.SetTotalCountHeader(filteredCount) | |||||
ctx.JSON(http.StatusOK, convert.ToAPIIssueList(issues)) | ctx.JSON(http.StatusOK, convert.ToAPIIssueList(issues)) | ||||
} | } | ||||
} | } | ||||
issue.Repo = ctx.Repo.Repository | issue.Repo = ctx.Repo.Repository | ||||
comments, err := models.FindComments(models.FindCommentsOptions{ | |||||
opts := &models.FindCommentsOptions{ | |||||
IssueID: issue.ID, | IssueID: issue.ID, | ||||
Since: since, | Since: since, | ||||
Before: before, | Before: before, | ||||
Type: models.CommentTypeComment, | Type: models.CommentTypeComment, | ||||
}) | |||||
} | |||||
comments, err := models.FindComments(opts) | |||||
if err != nil { | if err != nil { | ||||
ctx.Error(http.StatusInternalServerError, "FindComments", err) | ctx.Error(http.StatusInternalServerError, "FindComments", err) | ||||
return | return | ||||
} | } | ||||
totalCount, err := models.CountComments(opts) | |||||
if err != nil { | |||||
ctx.InternalServerError(err) | |||||
return | |||||
} | |||||
if err := models.CommentList(comments).LoadPosters(); err != nil { | if err := models.CommentList(comments).LoadPosters(); err != nil { | ||||
ctx.Error(http.StatusInternalServerError, "LoadPosters", err) | ctx.Error(http.StatusInternalServerError, "LoadPosters", err) | ||||
return | return | ||||
comment.Issue = issue | comment.Issue = issue | ||||
apiComments[i] = convert.ToComment(comments[i]) | apiComments[i] = convert.ToComment(comments[i]) | ||||
} | } | ||||
ctx.SetTotalCountHeader(totalCount) | |||||
ctx.JSON(http.StatusOK, &apiComments) | ctx.JSON(http.StatusOK, &apiComments) | ||||
} | } | ||||
return | return | ||||
} | } | ||||
comments, err := models.FindComments(models.FindCommentsOptions{ | |||||
opts := &models.FindCommentsOptions{ | |||||
ListOptions: utils.GetListOptions(ctx), | ListOptions: utils.GetListOptions(ctx), | ||||
RepoID: ctx.Repo.Repository.ID, | RepoID: ctx.Repo.Repository.ID, | ||||
Type: models.CommentTypeComment, | Type: models.CommentTypeComment, | ||||
Since: since, | Since: since, | ||||
Before: before, | Before: before, | ||||
}) | |||||
} | |||||
comments, err := models.FindComments(opts) | |||||
if err != nil { | if err != nil { | ||||
ctx.Error(http.StatusInternalServerError, "FindComments", err) | ctx.Error(http.StatusInternalServerError, "FindComments", err) | ||||
return | return | ||||
} | } | ||||
totalCount, err := models.CountComments(opts) | |||||
if err != nil { | |||||
ctx.InternalServerError(err) | |||||
return | |||||
} | |||||
if err = models.CommentList(comments).LoadPosters(); err != nil { | if err = models.CommentList(comments).LoadPosters(); err != nil { | ||||
ctx.Error(http.StatusInternalServerError, "LoadPosters", err) | ctx.Error(http.StatusInternalServerError, "LoadPosters", err) | ||||
return | return | ||||
for i := range comments { | for i := range comments { | ||||
apiComments[i] = convert.ToComment(comments[i]) | apiComments[i] = convert.ToComment(comments[i]) | ||||
} | } | ||||
ctx.SetTotalCountHeader(totalCount) | |||||
ctx.JSON(http.StatusOK, &apiComments) | ctx.JSON(http.StatusOK, &apiComments) | ||||
} | } | ||||
return | return | ||||
} | } | ||||
count, err := models.CountUserStopwatches(ctx.User.ID) | |||||
if err != nil { | |||||
ctx.InternalServerError(err) | |||||
return | |||||
} | |||||
apiSWs, err := convert.ToStopWatches(sws) | apiSWs, err := convert.ToStopWatches(sws) | ||||
if err != nil { | if err != nil { | ||||
ctx.Error(http.StatusInternalServerError, "APIFormat", err) | ctx.Error(http.StatusInternalServerError, "APIFormat", err) | ||||
return | return | ||||
} | } | ||||
ctx.SetTotalCountHeader(count) | |||||
ctx.JSON(http.StatusOK, apiSWs) | ctx.JSON(http.StatusOK, apiSWs) | ||||
} | } |
return | return | ||||
} | } | ||||
opts := models.FindTrackedTimesOptions{ | |||||
opts := &models.FindTrackedTimesOptions{ | |||||
ListOptions: utils.GetListOptions(ctx), | ListOptions: utils.GetListOptions(ctx), | ||||
RepositoryID: ctx.Repo.Repository.ID, | RepositoryID: ctx.Repo.Repository.ID, | ||||
IssueID: issue.ID, | IssueID: issue.ID, | ||||
} | } | ||||
} | } | ||||
count, err := models.CountTrackedTimes(opts) | |||||
if err != nil { | |||||
ctx.InternalServerError(err) | |||||
return | |||||
} | |||||
trackedTimes, err := models.GetTrackedTimes(opts) | trackedTimes, err := models.GetTrackedTimes(opts) | ||||
if err != nil { | if err != nil { | ||||
ctx.Error(http.StatusInternalServerError, "GetTrackedTimes", err) | ctx.Error(http.StatusInternalServerError, "GetTrackedTimes", err) | ||||
ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) | ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) | ||||
return | return | ||||
} | } | ||||
ctx.SetTotalCountHeader(count) | |||||
ctx.JSON(http.StatusOK, convert.ToTrackedTimeList(trackedTimes)) | ctx.JSON(http.StatusOK, convert.ToTrackedTimeList(trackedTimes)) | ||||
} | } | ||||
return | return | ||||
} | } | ||||
opts := models.FindTrackedTimesOptions{ | |||||
opts := &models.FindTrackedTimesOptions{ | |||||
UserID: user.ID, | UserID: user.ID, | ||||
RepositoryID: ctx.Repo.Repository.ID, | RepositoryID: ctx.Repo.Repository.ID, | ||||
} | } | ||||
return | return | ||||
} | } | ||||
opts := models.FindTrackedTimesOptions{ | |||||
opts := &models.FindTrackedTimesOptions{ | |||||
ListOptions: utils.GetListOptions(ctx), | ListOptions: utils.GetListOptions(ctx), | ||||
RepositoryID: ctx.Repo.Repository.ID, | RepositoryID: ctx.Repo.Repository.ID, | ||||
} | } | ||||
} | } | ||||
} | } | ||||
count, err := models.CountTrackedTimes(opts) | |||||
if err != nil { | |||||
ctx.InternalServerError(err) | |||||
return | |||||
} | |||||
trackedTimes, err := models.GetTrackedTimes(opts) | trackedTimes, err := models.GetTrackedTimes(opts) | ||||
if err != nil { | if err != nil { | ||||
ctx.Error(http.StatusInternalServerError, "GetTrackedTimes", err) | ctx.Error(http.StatusInternalServerError, "GetTrackedTimes", err) | ||||
ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) | ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) | ||||
return | return | ||||
} | } | ||||
ctx.SetTotalCountHeader(count) | |||||
ctx.JSON(http.StatusOK, convert.ToTrackedTimeList(trackedTimes)) | ctx.JSON(http.StatusOK, convert.ToTrackedTimeList(trackedTimes)) | ||||
} | } | ||||
// "200": | // "200": | ||||
// "$ref": "#/responses/TrackedTimeList" | // "$ref": "#/responses/TrackedTimeList" | ||||
opts := models.FindTrackedTimesOptions{ | |||||
opts := &models.FindTrackedTimesOptions{ | |||||
ListOptions: utils.GetListOptions(ctx), | ListOptions: utils.GetListOptions(ctx), | ||||
UserID: ctx.User.ID, | UserID: ctx.User.ID, | ||||
} | } | ||||
return | return | ||||
} | } | ||||
count, err := models.CountTrackedTimes(opts) | |||||
if err != nil { | |||||
ctx.InternalServerError(err) | |||||
return | |||||
} | |||||
trackedTimes, err := models.GetTrackedTimes(opts) | trackedTimes, err := models.GetTrackedTimes(opts) | ||||
if err != nil { | if err != nil { | ||||
ctx.Error(http.StatusInternalServerError, "GetTrackedTimesByUser", err) | ctx.Error(http.StatusInternalServerError, "GetTrackedTimesByUser", err) | ||||
return | return | ||||
} | } | ||||
ctx.SetTotalCountHeader(count) | |||||
ctx.JSON(http.StatusOK, convert.ToTrackedTimeList(trackedTimes)) | ctx.JSON(http.StatusOK, convert.ToTrackedTimeList(trackedTimes)) | ||||
} | } |
// "200": | // "200": | ||||
// "$ref": "#/responses/DeployKeyList" | // "$ref": "#/responses/DeployKeyList" | ||||
var keys []*models.DeployKey | |||||
var err error | |||||
opts := &models.ListDeployKeysOptions{ | |||||
ListOptions: utils.GetListOptions(ctx), | |||||
RepoID: ctx.Repo.Repository.ID, | |||||
KeyID: ctx.FormInt64("key_id"), | |||||
Fingerprint: ctx.FormString("fingerprint"), | |||||
} | |||||
fingerprint := ctx.FormString("fingerprint") | |||||
keyID := ctx.FormInt64("key_id") | |||||
if fingerprint != "" || keyID != 0 { | |||||
keys, err = models.SearchDeployKeys(ctx.Repo.Repository.ID, keyID, fingerprint) | |||||
} else { | |||||
keys, err = models.ListDeployKeys(ctx.Repo.Repository.ID, utils.GetListOptions(ctx)) | |||||
keys, err := models.ListDeployKeys(opts) | |||||
if err != nil { | |||||
ctx.InternalServerError(err) | |||||
return | |||||
} | } | ||||
count, err := models.CountDeployKeys(opts) | |||||
if err != nil { | if err != nil { | ||||
ctx.Error(http.StatusInternalServerError, "ListDeployKeys", err) | |||||
ctx.InternalServerError(err) | |||||
return | return | ||||
} | } | ||||
apiLink := composeDeployKeysAPILink(ctx.Repo.Owner.Name + "/" + ctx.Repo.Repository.Name) | apiLink := composeDeployKeysAPILink(ctx.Repo.Owner.Name + "/" + ctx.Repo.Repository.Name) | ||||
apiKeys := make([]*api.DeployKey, len(keys)) | apiKeys := make([]*api.DeployKey, len(keys)) | ||||
for i := range keys { | for i := range keys { | ||||
if err = keys[i].GetContent(); err != nil { | |||||
if err := keys[i].GetContent(); err != nil { | |||||
ctx.Error(http.StatusInternalServerError, "GetContent", err) | ctx.Error(http.StatusInternalServerError, "GetContent", err) | ||||
return | return | ||||
} | } | ||||
} | } | ||||
} | } | ||||
ctx.SetTotalCountHeader(count) | |||||
ctx.JSON(http.StatusOK, &apiKeys) | ctx.JSON(http.StatusOK, &apiKeys) | ||||
} | } | ||||
return | return | ||||
} | } | ||||
count, err := models.CountLabelsByRepoID(ctx.Repo.Repository.ID) | |||||
if err != nil { | |||||
ctx.InternalServerError(err) | |||||
return | |||||
} | |||||
ctx.SetTotalCountHeader(count) | |||||
ctx.JSON(http.StatusOK, convert.ToLabelList(labels)) | ctx.JSON(http.StatusOK, convert.ToLabelList(labels)) | ||||
} | } | ||||
// "200": | // "200": | ||||
// "$ref": "#/responses/MilestoneList" | // "$ref": "#/responses/MilestoneList" | ||||
milestones, err := models.GetMilestones(models.GetMilestonesOption{ | |||||
milestones, total, err := models.GetMilestones(models.GetMilestonesOption{ | |||||
ListOptions: utils.GetListOptions(ctx), | ListOptions: utils.GetListOptions(ctx), | ||||
RepoID: ctx.Repo.Repository.ID, | RepoID: ctx.Repo.Repository.ID, | ||||
State: api.StateType(ctx.FormString("state")), | State: api.StateType(ctx.FormString("state")), | ||||
for i := range milestones { | for i := range milestones { | ||||
apiMilestones[i] = convert.ToAPIMilestone(milestones[i]) | apiMilestones[i] = convert.ToAPIMilestone(milestones[i]) | ||||
} | } | ||||
ctx.SetTotalCountHeader(total) | |||||
ctx.JSON(http.StatusOK, &apiMilestones) | ctx.JSON(http.StatusOK, &apiMilestones) | ||||
} | } | ||||
} | } | ||||
ctx.SetLinkHeader(int(maxResults), listOptions.PageSize) | ctx.SetLinkHeader(int(maxResults), listOptions.PageSize) | ||||
ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", maxResults)) | |||||
ctx.Header().Set("Access-Control-Expose-Headers", "X-Total-Count, Link") | |||||
ctx.SetTotalCountHeader(maxResults) | |||||
ctx.JSON(http.StatusOK, &apiPrs) | ctx.JSON(http.StatusOK, &apiPrs) | ||||
} | } | ||||
apiCommits = append(apiCommits, apiCommit) | apiCommits = append(apiCommits, apiCommit) | ||||
} | } | ||||
ctx.SetLinkHeader(int(totalNumberOfCommits), listOptions.PageSize) | |||||
ctx.SetLinkHeader(totalNumberOfCommits, listOptions.PageSize) | |||||
ctx.SetTotalCountHeader(int64(totalNumberOfCommits)) | |||||
ctx.Header().Set("X-Page", strconv.Itoa(listOptions.Page)) | ctx.Header().Set("X-Page", strconv.Itoa(listOptions.Page)) | ||||
ctx.Header().Set("X-PerPage", strconv.Itoa(listOptions.PageSize)) | ctx.Header().Set("X-PerPage", strconv.Itoa(listOptions.PageSize)) | ||||
ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", totalNumberOfCommits)) | |||||
ctx.Header().Set("X-PageCount", strconv.Itoa(totalNumberOfPages)) | ctx.Header().Set("X-PageCount", strconv.Itoa(totalNumberOfPages)) | ||||
ctx.Header().Set("X-HasMore", strconv.FormatBool(listOptions.Page < totalNumberOfPages)) | ctx.Header().Set("X-HasMore", strconv.FormatBool(listOptions.Page < totalNumberOfPages)) | ||||
ctx.Header().Set("Access-Control-Expose-Headers", "X-Total-Count, X-PerPage, X-Total, X-PageCount, X-HasMore, Link") | |||||
ctx.AppendAccessControlExposeHeaders("X-Page", "X-PerPage", "X-PageCount", "X-HasMore") | |||||
ctx.JSON(http.StatusOK, &apiCommits) | ctx.JSON(http.StatusOK, &apiCommits) | ||||
} | } |
return | return | ||||
} | } | ||||
allReviews, err := models.FindReviews(models.FindReviewOptions{ | |||||
opts := models.FindReviewOptions{ | |||||
ListOptions: utils.GetListOptions(ctx), | ListOptions: utils.GetListOptions(ctx), | ||||
Type: models.ReviewTypeUnknown, | Type: models.ReviewTypeUnknown, | ||||
IssueID: pr.IssueID, | IssueID: pr.IssueID, | ||||
}) | |||||
} | |||||
allReviews, err := models.FindReviews(opts) | |||||
if err != nil { | |||||
ctx.InternalServerError(err) | |||||
return | |||||
} | |||||
count, err := models.CountReviews(opts) | |||||
if err != nil { | if err != nil { | ||||
ctx.Error(http.StatusInternalServerError, "FindReviews", err) | |||||
ctx.InternalServerError(err) | |||||
return | return | ||||
} | } | ||||
return | return | ||||
} | } | ||||
ctx.SetTotalCountHeader(count) | |||||
ctx.JSON(http.StatusOK, &apiReviews) | ctx.JSON(http.StatusOK, &apiReviews) | ||||
} | } | ||||
package repo | package repo | ||||
import ( | import ( | ||||
"fmt" | |||||
"net/http" | "net/http" | ||||
"code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
} | } | ||||
ctx.SetLinkHeader(int(filteredCount), listOptions.PageSize) | ctx.SetLinkHeader(int(filteredCount), listOptions.PageSize) | ||||
ctx.Header().Set("X-Total-Count", fmt.Sprint(filteredCount)) | |||||
ctx.Header().Set("Access-Control-Expose-Headers", "X-Total-Count, Link") | |||||
ctx.SetTotalCountHeader(filteredCount) | |||||
ctx.JSON(http.StatusOK, rels) | ctx.JSON(http.StatusOK, rels) | ||||
} | } | ||||
} | } | ||||
ctx.SetLinkHeader(int(count), opts.PageSize) | ctx.SetLinkHeader(int(count), opts.PageSize) | ||||
ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", count)) | |||||
ctx.Header().Set("Access-Control-Expose-Headers", "X-Total-Count, Link") | |||||
ctx.SetTotalCountHeader(count) | |||||
ctx.JSON(http.StatusOK, api.SearchResults{ | ctx.JSON(http.StatusOK, api.SearchResults{ | ||||
OK: true, | OK: true, | ||||
Data: results, | Data: results, |
for i, stargazer := range stargazers { | for i, stargazer := range stargazers { | ||||
users[i] = convert.ToUser(stargazer, ctx.User) | users[i] = convert.ToUser(stargazer, ctx.User) | ||||
} | } | ||||
ctx.SetTotalCountHeader(int64(ctx.Repo.Repository.NumStars)) | |||||
ctx.JSON(http.StatusOK, users) | ctx.JSON(http.StatusOK, users) | ||||
} | } |
} | } | ||||
ctx.SetLinkHeader(int(maxResults), listOptions.PageSize) | ctx.SetLinkHeader(int(maxResults), listOptions.PageSize) | ||||
ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", maxResults)) | |||||
ctx.Header().Set("Access-Control-Expose-Headers", "X-Total-Count, Link") | |||||
ctx.SetTotalCountHeader(maxResults) | |||||
ctx.JSON(http.StatusOK, apiStatuses) | ctx.JSON(http.StatusOK, apiStatuses) | ||||
} | } | ||||
combiStatus := convert.ToCombinedStatus(statuses, convert.ToRepo(repo, ctx.Repo.AccessMode)) | combiStatus := convert.ToCombinedStatus(statuses, convert.ToRepo(repo, ctx.Repo.AccessMode)) | ||||
// TODO: ctx.SetTotalCountHeader(count) | |||||
ctx.JSON(http.StatusOK, combiStatus) | ctx.JSON(http.StatusOK, combiStatus) | ||||
} | } |
for i, subscriber := range subscribers { | for i, subscriber := range subscribers { | ||||
users[i] = convert.ToUser(subscriber, ctx.User) | users[i] = convert.ToUser(subscriber, ctx.User) | ||||
} | } | ||||
ctx.SetTotalCountHeader(int64(ctx.Repo.Repository.NumWatches)) | |||||
ctx.JSON(http.StatusOK, users) | ctx.JSON(http.StatusOK, users) | ||||
} | } |
listOpts := utils.GetListOptions(ctx) | listOpts := utils.GetListOptions(ctx) | ||||
tags, err := ctx.Repo.GitRepo.GetTagInfos(listOpts.Page, listOpts.PageSize) | |||||
tags, total, err := ctx.Repo.GitRepo.GetTagInfos(listOpts.Page, listOpts.PageSize) | |||||
if err != nil { | if err != nil { | ||||
ctx.Error(http.StatusInternalServerError, "GetTags", err) | ctx.Error(http.StatusInternalServerError, "GetTags", err) | ||||
return | return | ||||
apiTags[i] = convert.ToTag(ctx.Repo.Repository, tags[i]) | apiTags[i] = convert.ToTag(ctx.Repo.Repository, tags[i]) | ||||
} | } | ||||
ctx.SetTotalCountHeader(int64(total)) | |||||
ctx.JSON(http.StatusOK, &apiTags) | ctx.JSON(http.StatusOK, &apiTags) | ||||
} | } | ||||
// "200": | // "200": | ||||
// "$ref": "#/responses/TopicNames" | // "$ref": "#/responses/TopicNames" | ||||
topics, err := models.FindTopics(&models.FindTopicOptions{ | |||||
opts := &models.FindTopicOptions{ | |||||
ListOptions: utils.GetListOptions(ctx), | ListOptions: utils.GetListOptions(ctx), | ||||
RepoID: ctx.Repo.Repository.ID, | RepoID: ctx.Repo.Repository.ID, | ||||
}) | |||||
} | |||||
topics, total, err := models.FindTopics(opts) | |||||
if err != nil { | if err != nil { | ||||
log.Error("ListTopics failed: %v", err) | |||||
ctx.InternalServerError(err) | ctx.InternalServerError(err) | ||||
return | return | ||||
} | } | ||||
for i, topic := range topics { | for i, topic := range topics { | ||||
topicNames[i] = topic.Name | topicNames[i] = topic.Name | ||||
} | } | ||||
ctx.SetTotalCountHeader(total) | |||||
ctx.JSON(http.StatusOK, map[string]interface{}{ | ctx.JSON(http.StatusOK, map[string]interface{}{ | ||||
"topics": topicNames, | "topics": topicNames, | ||||
}) | }) | ||||
} | } | ||||
// Prevent adding more topics than allowed to repo | // Prevent adding more topics than allowed to repo | ||||
topics, err := models.FindTopics(&models.FindTopicOptions{ | |||||
count, err := models.CountTopics(&models.FindTopicOptions{ | |||||
RepoID: ctx.Repo.Repository.ID, | RepoID: ctx.Repo.Repository.ID, | ||||
}) | }) | ||||
if err != nil { | if err != nil { | ||||
log.Error("AddTopic failed: %v", err) | |||||
log.Error("CountTopics failed: %v", err) | |||||
ctx.InternalServerError(err) | ctx.InternalServerError(err) | ||||
return | return | ||||
} | } | ||||
if len(topics) >= 25 { | |||||
if count >= 25 { | |||||
ctx.JSON(http.StatusUnprocessableEntity, map[string]interface{}{ | ctx.JSON(http.StatusUnprocessableEntity, map[string]interface{}{ | ||||
"message": "Exceeding maximum allowed topics per repo.", | "message": "Exceeding maximum allowed topics per repo.", | ||||
}) | }) | ||||
// "403": | // "403": | ||||
// "$ref": "#/responses/forbidden" | // "$ref": "#/responses/forbidden" | ||||
if ctx.User == nil { | |||||
ctx.Error(http.StatusForbidden, "UserIsNil", "Only owners could change the topics.") | |||||
return | |||||
opts := &models.FindTopicOptions{ | |||||
Keyword: ctx.FormString("q"), | |||||
ListOptions: utils.GetListOptions(ctx), | |||||
} | } | ||||
kw := ctx.FormString("q") | |||||
listOptions := utils.GetListOptions(ctx) | |||||
topics, err := models.FindTopics(&models.FindTopicOptions{ | |||||
Keyword: kw, | |||||
ListOptions: listOptions, | |||||
}) | |||||
topics, total, err := models.FindTopics(opts) | |||||
if err != nil { | if err != nil { | ||||
log.Error("SearchTopics failed: %v", err) | |||||
ctx.InternalServerError(err) | ctx.InternalServerError(err) | ||||
return | return | ||||
} | } | ||||
for i, topic := range topics { | for i, topic := range topics { | ||||
topicResponses[i] = convert.ToTopicResponse(topic) | topicResponses[i] = convert.ToTopicResponse(topic) | ||||
} | } | ||||
ctx.SetTotalCountHeader(total) | |||||
ctx.JSON(http.StatusOK, map[string]interface{}{ | ctx.JSON(http.StatusOK, map[string]interface{}{ | ||||
"topics": topicResponses, | "topics": topicResponses, | ||||
}) | }) |
// "200": | // "200": | ||||
// "$ref": "#/responses/AccessTokenList" | // "$ref": "#/responses/AccessTokenList" | ||||
tokens, err := models.ListAccessTokens(models.ListAccessTokensOptions{UserID: ctx.User.ID, ListOptions: utils.GetListOptions(ctx)}) | |||||
opts := models.ListAccessTokensOptions{UserID: ctx.User.ID, ListOptions: utils.GetListOptions(ctx)} | |||||
count, err := models.CountAccessTokens(opts) | |||||
if err != nil { | |||||
ctx.InternalServerError(err) | |||||
return | |||||
} | |||||
tokens, err := models.ListAccessTokens(opts) | |||||
if err != nil { | if err != nil { | ||||
ctx.Error(http.StatusInternalServerError, "ListAccessTokens", err) | |||||
ctx.InternalServerError(err) | |||||
return | return | ||||
} | } | ||||
TokenLastEight: tokens[i].TokenLastEight, | TokenLastEight: tokens[i].TokenLastEight, | ||||
} | } | ||||
} | } | ||||
ctx.SetTotalCountHeader(count) | |||||
ctx.JSON(http.StatusOK, &apiTokens) | ctx.JSON(http.StatusOK, &apiTokens) | ||||
} | } | ||||
// "200": | // "200": | ||||
// "$ref": "#/responses/OAuth2ApplicationList" | // "$ref": "#/responses/OAuth2ApplicationList" | ||||
apps, err := models.ListOAuth2Applications(ctx.User.ID, utils.GetListOptions(ctx)) | |||||
apps, total, err := models.ListOAuth2Applications(ctx.User.ID, utils.GetListOptions(ctx)) | |||||
if err != nil { | if err != nil { | ||||
ctx.Error(http.StatusInternalServerError, "ListOAuth2Applications", err) | ctx.Error(http.StatusInternalServerError, "ListOAuth2Applications", err) | ||||
return | return | ||||
apiApps[i] = convert.ToOAuth2Application(apps[i]) | apiApps[i] = convert.ToOAuth2Application(apps[i]) | ||||
apiApps[i].ClientSecret = "" // Hide secret on application list | apiApps[i].ClientSecret = "" // Hide secret on application list | ||||
} | } | ||||
ctx.SetTotalCountHeader(total) | |||||
ctx.JSON(http.StatusOK, &apiApps) | ctx.JSON(http.StatusOK, &apiApps) | ||||
} | } | ||||
ctx.Error(http.StatusInternalServerError, "GetUserFollowers", err) | ctx.Error(http.StatusInternalServerError, "GetUserFollowers", err) | ||||
return | return | ||||
} | } | ||||
ctx.SetTotalCountHeader(int64(u.NumFollowers)) | |||||
responseAPIUsers(ctx, users) | responseAPIUsers(ctx, users) | ||||
} | } | ||||
ctx.Error(http.StatusInternalServerError, "GetFollowing", err) | ctx.Error(http.StatusInternalServerError, "GetFollowing", err) | ||||
return | return | ||||
} | } | ||||
ctx.SetTotalCountHeader(int64(u.NumFollowing)) | |||||
responseAPIUsers(ctx, users) | responseAPIUsers(ctx, users) | ||||
} | } | ||||
apiKeys[i] = convert.ToGPGKey(keys[i]) | apiKeys[i] = convert.ToGPGKey(keys[i]) | ||||
} | } | ||||
total, err := models.CountUserGPGKeys(uid) | |||||
if err != nil { | |||||
ctx.InternalServerError(err) | |||||
return | |||||
} | |||||
ctx.SetTotalCountHeader(total) | |||||
ctx.JSON(http.StatusOK, &apiKeys) | ctx.JSON(http.StatusOK, &apiKeys) | ||||
} | } | ||||
func listPublicKeys(ctx *context.APIContext, user *models.User) { | func listPublicKeys(ctx *context.APIContext, user *models.User) { | ||||
var keys []*models.PublicKey | var keys []*models.PublicKey | ||||
var err error | var err error | ||||
var count int | |||||
fingerprint := ctx.FormString("fingerprint") | fingerprint := ctx.FormString("fingerprint") | ||||
username := ctx.Params("username") | username := ctx.Params("username") | ||||
// Unrestricted | // Unrestricted | ||||
keys, err = models.SearchPublicKey(0, fingerprint) | keys, err = models.SearchPublicKey(0, fingerprint) | ||||
} | } | ||||
count = len(keys) | |||||
} else { | } else { | ||||
total, err2 := models.CountPublicKeys(user.ID) | |||||
if err2 != nil { | |||||
ctx.InternalServerError(err) | |||||
return | |||||
} | |||||
count = int(total) | |||||
// Use ListPublicKeys | // Use ListPublicKeys | ||||
keys, err = models.ListPublicKeys(user.ID, utils.GetListOptions(ctx)) | keys, err = models.ListPublicKeys(user.ID, utils.GetListOptions(ctx)) | ||||
} | } | ||||
} | } | ||||
} | } | ||||
ctx.SetTotalCountHeader(int64(count)) | |||||
ctx.JSON(http.StatusOK, &apiKeys) | ctx.JSON(http.StatusOK, &apiKeys) | ||||
} | } | ||||
import ( | import ( | ||||
"net/http" | "net/http" | ||||
"strconv" | |||||
"code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
"code.gitea.io/gitea/modules/context" | "code.gitea.io/gitea/modules/context" | ||||
} | } | ||||
ctx.SetLinkHeader(int(count), opts.PageSize) | ctx.SetLinkHeader(int(count), opts.PageSize) | ||||
ctx.Header().Set("X-Total-Count", strconv.FormatInt(count, 10)) | |||||
ctx.Header().Set("Access-Control-Expose-Headers", "X-Total-Count, Link") | |||||
ctx.SetTotalCountHeader(count) | |||||
ctx.JSON(http.StatusOK, &apiRepos) | ctx.JSON(http.StatusOK, &apiRepos) | ||||
} | } | ||||
} | } | ||||
ctx.SetLinkHeader(int(count), opts.ListOptions.PageSize) | ctx.SetLinkHeader(int(count), opts.ListOptions.PageSize) | ||||
ctx.Header().Set("X-Total-Count", strconv.FormatInt(count, 10)) | |||||
ctx.Header().Set("Access-Control-Expose-Headers", "X-Total-Count, Link") | |||||
ctx.SetTotalCountHeader(count) | |||||
ctx.JSON(http.StatusOK, &results) | ctx.JSON(http.StatusOK, &results) | ||||
} | } | ||||
if err != nil { | if err != nil { | ||||
ctx.Error(http.StatusInternalServerError, "getStarredRepos", err) | ctx.Error(http.StatusInternalServerError, "getStarredRepos", err) | ||||
} | } | ||||
ctx.SetTotalCountHeader(int64(ctx.User.NumStars)) | |||||
ctx.JSON(http.StatusOK, &repos) | ctx.JSON(http.StatusOK, &repos) | ||||
} | } | ||||
package user | package user | ||||
import ( | import ( | ||||
"fmt" | |||||
"net/http" | "net/http" | ||||
"code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
} | } | ||||
ctx.SetLinkHeader(int(maxResults), listOptions.PageSize) | ctx.SetLinkHeader(int(maxResults), listOptions.PageSize) | ||||
ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", maxResults)) | |||||
ctx.Header().Set("Access-Control-Expose-Headers", "X-Total-Count, Link") | |||||
ctx.SetTotalCountHeader(maxResults) | |||||
ctx.JSON(http.StatusOK, map[string]interface{}{ | ctx.JSON(http.StatusOK, map[string]interface{}{ | ||||
"ok": true, | "ok": true, |
"code.gitea.io/gitea/routers/api/v1/utils" | "code.gitea.io/gitea/routers/api/v1/utils" | ||||
) | ) | ||||
// getWatchedRepos returns the repos that the user with the specified userID is | |||||
// watching | |||||
func getWatchedRepos(user *models.User, private bool, listOptions models.ListOptions) ([]*api.Repository, error) { | |||||
watchedRepos, err := models.GetWatchedRepos(user.ID, private, listOptions) | |||||
// getWatchedRepos returns the repos that the user with the specified userID is watching | |||||
func getWatchedRepos(user *models.User, private bool, listOptions models.ListOptions) ([]*api.Repository, int64, error) { | |||||
watchedRepos, total, err := models.GetWatchedRepos(user.ID, private, listOptions) | |||||
if err != nil { | if err != nil { | ||||
return nil, err | |||||
return nil, 0, err | |||||
} | } | ||||
repos := make([]*api.Repository, len(watchedRepos)) | repos := make([]*api.Repository, len(watchedRepos)) | ||||
for i, watched := range watchedRepos { | for i, watched := range watchedRepos { | ||||
access, err := models.AccessLevel(user, watched) | access, err := models.AccessLevel(user, watched) | ||||
if err != nil { | if err != nil { | ||||
return nil, err | |||||
return nil, 0, err | |||||
} | } | ||||
repos[i] = convert.ToRepo(watched, access) | repos[i] = convert.ToRepo(watched, access) | ||||
} | } | ||||
return repos, nil | |||||
return repos, total, nil | |||||
} | } | ||||
// GetWatchedRepos returns the repos that the user specified in ctx is watching | // GetWatchedRepos returns the repos that the user specified in ctx is watching | ||||
user := GetUserByParams(ctx) | user := GetUserByParams(ctx) | ||||
private := user.ID == ctx.User.ID | private := user.ID == ctx.User.ID | ||||
repos, err := getWatchedRepos(user, private, utils.GetListOptions(ctx)) | |||||
repos, total, err := getWatchedRepos(user, private, utils.GetListOptions(ctx)) | |||||
if err != nil { | if err != nil { | ||||
ctx.Error(http.StatusInternalServerError, "getWatchedRepos", err) | ctx.Error(http.StatusInternalServerError, "getWatchedRepos", err) | ||||
} | } | ||||
ctx.SetTotalCountHeader(total) | |||||
ctx.JSON(http.StatusOK, &repos) | ctx.JSON(http.StatusOK, &repos) | ||||
} | } | ||||
// "200": | // "200": | ||||
// "$ref": "#/responses/RepositoryList" | // "$ref": "#/responses/RepositoryList" | ||||
repos, err := getWatchedRepos(ctx.User, true, utils.GetListOptions(ctx)) | |||||
repos, total, err := getWatchedRepos(ctx.User, true, utils.GetListOptions(ctx)) | |||||
if err != nil { | if err != nil { | ||||
ctx.Error(http.StatusInternalServerError, "getWatchedRepos", err) | ctx.Error(http.StatusInternalServerError, "getWatchedRepos", err) | ||||
} | } | ||||
ctx.SetTotalCountHeader(total) | |||||
ctx.JSON(http.StatusOK, &repos) | ctx.JSON(http.StatusOK, &repos) | ||||
} | } | ||||
return | return | ||||
} | } | ||||
var opts = models.FindOrgMembersOpts{ | |||||
var opts = &models.FindOrgMembersOpts{ | |||||
OrgID: org.ID, | OrgID: org.ID, | ||||
PublicOnly: true, | PublicOnly: true, | ||||
ListOptions: models.ListOptions{Page: 1, PageSize: 25}, | ListOptions: models.ListOptions{Page: 1, PageSize: 25}, | ||||
opts.PublicOnly = !isMember && !ctx.User.IsAdmin | opts.PublicOnly = !isMember && !ctx.User.IsAdmin | ||||
} | } | ||||
members, _, err := models.FindOrgMembers(&opts) | |||||
members, _, err := models.FindOrgMembers(opts) | |||||
if err != nil { | if err != nil { | ||||
ctx.ServerError("FindOrgMembers", err) | ctx.ServerError("FindOrgMembers", err) | ||||
return | return |
page = 1 | page = 1 | ||||
} | } | ||||
var opts = models.FindOrgMembersOpts{ | |||||
var opts = &models.FindOrgMembersOpts{ | |||||
OrgID: org.ID, | OrgID: org.ID, | ||||
PublicOnly: true, | PublicOnly: true, | ||||
} | } | ||||
pager := context.NewPagination(int(total), setting.UI.MembersPagingNum, page, 5) | pager := context.NewPagination(int(total), setting.UI.MembersPagingNum, page, 5) | ||||
opts.ListOptions.Page = page | opts.ListOptions.Page = page | ||||
opts.ListOptions.PageSize = setting.UI.MembersPagingNum | opts.ListOptions.PageSize = setting.UI.MembersPagingNum | ||||
members, membersIsPublic, err := models.FindOrgMembers(&opts) | |||||
members, membersIsPublic, err := models.FindOrgMembers(opts) | |||||
if err != nil { | if err != nil { | ||||
ctx.ServerError("GetMembers", err) | ctx.ServerError("GetMembers", err) | ||||
return | return |
ctx.Data["BaseLinkNew"] = ctx.Org.OrgLink + "/settings/hooks" | ctx.Data["BaseLinkNew"] = ctx.Org.OrgLink + "/settings/hooks" | ||||
ctx.Data["Description"] = ctx.Tr("org.settings.hooks_desc") | ctx.Data["Description"] = ctx.Tr("org.settings.hooks_desc") | ||||
ws, err := models.GetWebhooksByOrgID(ctx.Org.Organization.ID, models.ListOptions{}) | |||||
ws, err := models.ListWebhooksByOpts(&models.ListWebhookOptions{OrgID: ctx.Org.Organization.ID}) | |||||
if err != nil { | if err != nil { | ||||
ctx.ServerError("GetWebhooksByOrgId", err) | ctx.ServerError("GetWebhooksByOrgId", err) | ||||
return | return |
var err error | var err error | ||||
// Get milestones | // Get milestones | ||||
ctx.Data["Milestones"], err = models.GetMilestones(models.GetMilestonesOption{ | |||||
ctx.Data["Milestones"], _, err = models.GetMilestones(models.GetMilestonesOption{ | |||||
RepoID: ctx.Repo.Repository.ID, | RepoID: ctx.Repo.Repository.ID, | ||||
State: api.StateType(ctx.FormString("state")), | State: api.StateType(ctx.FormString("state")), | ||||
}) | }) | ||||
// RetrieveRepoMilestonesAndAssignees find all the milestones and assignees of a repository | // RetrieveRepoMilestonesAndAssignees find all the milestones and assignees of a repository | ||||
func RetrieveRepoMilestonesAndAssignees(ctx *context.Context, repo *models.Repository) { | func RetrieveRepoMilestonesAndAssignees(ctx *context.Context, repo *models.Repository) { | ||||
var err error | var err error | ||||
ctx.Data["OpenMilestones"], err = models.GetMilestones(models.GetMilestonesOption{ | |||||
ctx.Data["OpenMilestones"], _, err = models.GetMilestones(models.GetMilestonesOption{ | |||||
RepoID: repo.ID, | RepoID: repo.ID, | ||||
State: api.StateOpen, | State: api.StateOpen, | ||||
}) | }) | ||||
ctx.ServerError("GetMilestones", err) | ctx.ServerError("GetMilestones", err) | ||||
return | return | ||||
} | } | ||||
ctx.Data["ClosedMilestones"], err = models.GetMilestones(models.GetMilestonesOption{ | |||||
ctx.Data["ClosedMilestones"], _, err = models.GetMilestones(models.GetMilestonesOption{ | |||||
RepoID: repo.ID, | RepoID: repo.ID, | ||||
State: api.StateClosed, | State: api.StateClosed, | ||||
}) | }) | ||||
} else { | } else { | ||||
ctx.Data["CanUseTimetracker"] = false | ctx.Data["CanUseTimetracker"] = false | ||||
} | } | ||||
if ctx.Data["WorkingUsers"], err = models.TotalTimes(models.FindTrackedTimesOptions{IssueID: issue.ID}); err != nil { | |||||
if ctx.Data["WorkingUsers"], err = models.TotalTimes(&models.FindTrackedTimesOptions{IssueID: issue.ID}); err != nil { | |||||
ctx.ServerError("TotalTimes", err) | ctx.ServerError("TotalTimes", err) | ||||
return | return | ||||
} | } | ||||
} | } | ||||
if isAdmin { | if isAdmin { | ||||
if err := ctx.Repo.Owner.GetTeams(&models.SearchTeamOptions{}); err != nil { | |||||
ctx.ServerError("GetTeams", err) | |||||
if err := ctx.Repo.Owner.LoadTeams(); err != nil { | |||||
ctx.ServerError("LoadTeams", err) | |||||
return | return | ||||
} | } | ||||
} else { | } else { |
page = 1 | page = 1 | ||||
} | } | ||||
var total int | |||||
var state structs.StateType | |||||
if !isShowClosed { | |||||
total = int(stats.OpenCount) | |||||
state = structs.StateOpen | |||||
} else { | |||||
total = int(stats.ClosedCount) | |||||
state := structs.StateOpen | |||||
if isShowClosed { | |||||
state = structs.StateClosed | state = structs.StateClosed | ||||
} | } | ||||
miles, err := models.GetMilestones(models.GetMilestonesOption{ | |||||
miles, total, err := models.GetMilestones(models.GetMilestonesOption{ | |||||
ListOptions: models.ListOptions{ | ListOptions: models.ListOptions{ | ||||
Page: page, | Page: page, | ||||
PageSize: setting.UI.IssuePagingNum, | PageSize: setting.UI.IssuePagingNum, | ||||
ctx.Data["Keyword"] = keyword | ctx.Data["Keyword"] = keyword | ||||
ctx.Data["IsShowClosed"] = isShowClosed | ctx.Data["IsShowClosed"] = isShowClosed | ||||
pager := context.NewPagination(total, setting.UI.IssuePagingNum, page, 5) | |||||
pager := context.NewPagination(int(total), setting.UI.IssuePagingNum, page, 5) | |||||
pager.AddParam(ctx, "state", "State") | pager.AddParam(ctx, "state", "State") | ||||
pager.AddParam(ctx, "q", "Keyword") | pager.AddParam(ctx, "q", "Keyword") | ||||
ctx.Data["Page"] = pager | ctx.Data["Page"] = pager |
ctx.Data["PageIsSettingsKeys"] = true | ctx.Data["PageIsSettingsKeys"] = true | ||||
ctx.Data["DisableSSH"] = setting.SSH.Disabled | ctx.Data["DisableSSH"] = setting.SSH.Disabled | ||||
keys, err := models.ListDeployKeys(ctx.Repo.Repository.ID, models.ListOptions{}) | |||||
keys, err := models.ListDeployKeys(&models.ListDeployKeysOptions{RepoID: ctx.Repo.Repository.ID}) | |||||
if err != nil { | if err != nil { | ||||
ctx.ServerError("ListDeployKeys", err) | ctx.ServerError("ListDeployKeys", err) | ||||
return | return | ||||
ctx.Data["Title"] = ctx.Tr("repo.settings.deploy_keys") | ctx.Data["Title"] = ctx.Tr("repo.settings.deploy_keys") | ||||
ctx.Data["PageIsSettingsKeys"] = true | ctx.Data["PageIsSettingsKeys"] = true | ||||
keys, err := models.ListDeployKeys(ctx.Repo.Repository.ID, models.ListOptions{}) | |||||
keys, err := models.ListDeployKeys(&models.ListDeployKeysOptions{RepoID: ctx.Repo.Repository.ID}) | |||||
if err != nil { | if err != nil { | ||||
ctx.ServerError("ListDeployKeys", err) | ctx.ServerError("ListDeployKeys", err) | ||||
return | return |
} | } | ||||
func renderRepoTopics(ctx *context.Context) { | func renderRepoTopics(ctx *context.Context) { | ||||
topics, err := models.FindTopics(&models.FindTopicOptions{ | |||||
topics, _, err := models.FindTopics(&models.FindTopicOptions{ | |||||
RepoID: ctx.Repo.Repository.ID, | RepoID: ctx.Repo.Repository.ID, | ||||
}) | }) | ||||
if err != nil { | if err != nil { |
ctx.Data["BaseLinkNew"] = ctx.Repo.RepoLink + "/settings/hooks" | ctx.Data["BaseLinkNew"] = ctx.Repo.RepoLink + "/settings/hooks" | ||||
ctx.Data["Description"] = ctx.Tr("repo.settings.hooks_desc", "https://docs.gitea.io/en-us/webhooks/") | ctx.Data["Description"] = ctx.Tr("repo.settings.hooks_desc", "https://docs.gitea.io/en-us/webhooks/") | ||||
ws, err := models.GetWebhooksByRepoID(ctx.Repo.Repository.ID, models.ListOptions{}) | |||||
ws, err := models.ListWebhooksByOpts(&models.ListWebhookOptions{RepoID: ctx.Repo.Repository.ID}) | |||||
if err != nil { | if err != nil { | ||||
ctx.ServerError("GetWebhooksByRepoID", err) | ctx.ServerError("GetWebhooksByRepoID", err) | ||||
return | return |
head := pr.GetGitRefName() | head := pr.GetGitRefName() | ||||
if line > 0 { | if line > 0 { | ||||
if reviewID != 0 { | if reviewID != 0 { | ||||
first, err := models.FindComments(models.FindCommentsOptions{ | |||||
first, err := models.FindComments(&models.FindCommentsOptions{ | |||||
ReviewID: reviewID, | ReviewID: reviewID, | ||||
Line: line, | Line: line, | ||||
TreePath: treePath, | TreePath: treePath, |
"code.gitea.io/gitea/modules/setting" | "code.gitea.io/gitea/modules/setting" | ||||
api "code.gitea.io/gitea/modules/structs" | api "code.gitea.io/gitea/modules/structs" | ||||
"code.gitea.io/gitea/modules/sync" | "code.gitea.io/gitea/modules/sync" | ||||
"code.gitea.io/gitea/modules/util" | |||||
"github.com/gobwas/glob" | "github.com/gobwas/glob" | ||||
) | ) | ||||
} | } | ||||
func prepareWebhooks(repo *models.Repository, event models.HookEventType, p api.Payloader) error { | func prepareWebhooks(repo *models.Repository, event models.HookEventType, p api.Payloader) error { | ||||
ws, err := models.GetActiveWebhooksByRepoID(repo.ID) | |||||
ws, err := models.ListWebhooksByOpts(&models.ListWebhookOptions{ | |||||
RepoID: repo.ID, | |||||
IsActive: util.OptionalBoolTrue, | |||||
}) | |||||
if err != nil { | if err != nil { | ||||
return fmt.Errorf("GetActiveWebhooksByRepoID: %v", err) | return fmt.Errorf("GetActiveWebhooksByRepoID: %v", err) | ||||
} | } | ||||
// check if repo belongs to org and append additional webhooks | // check if repo belongs to org and append additional webhooks | ||||
if repo.MustOwner().IsOrganization() { | if repo.MustOwner().IsOrganization() { | ||||
// get hooks for org | // get hooks for org | ||||
orgHooks, err := models.GetActiveWebhooksByOrgID(repo.OwnerID) | |||||
orgHooks, err := models.ListWebhooksByOpts(&models.ListWebhookOptions{ | |||||
OrgID: repo.OwnerID, | |||||
IsActive: util.OptionalBoolTrue, | |||||
}) | |||||
if err != nil { | if err != nil { | ||||
return fmt.Errorf("GetActiveWebhooksByOrgID: %v", err) | return fmt.Errorf("GetActiveWebhooksByOrgID: %v", err) | ||||
} | } |