aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEthan Koenig <ethantkoenig@gmail.com>2016-11-14 17:33:58 -0500
committerEthan Koenig <ethantkoenig@gmail.com>2016-11-16 22:51:54 -0500
commit0834e492c06e30d30c2bc8eec4fcb6c499a62ced (patch)
tree9a7888958b31770b2a4a4411e08095452f1d5e4a
parent871c964ef7aaf70af5e9eab00a3d6642432b122a (diff)
downloadgitea-0834e492c06e30d30c2bc8eec4fcb6c499a62ced.tar.gz
gitea-0834e492c06e30d30c2bc8eec4fcb6c499a62ced.zip
API endpoints for stars
-rw-r--r--models/user.go15
-rw-r--r--modules/context/api.go31
-rw-r--r--routers/api/v1/api.go14
-rw-r--r--routers/api/v1/repo/repo.go36
-rw-r--r--routers/api/v1/user/star.go76
5 files changed, 138 insertions, 34 deletions
diff --git a/models/user.go b/models/user.go
index 0b6063fbc9..e8c5c91680 100644
--- a/models/user.go
+++ b/models/user.go
@@ -1179,3 +1179,18 @@ func UnfollowUser(userID, followID int64) (err error) {
}
return sess.Commit()
}
+
+// GetStarredRepos returns the repos starred by a particular user
+func GetStarredRepos(userID int64, private bool) ([]*Repository, error) {
+ sess := x.Where("star.uid=?", userID).
+ Join("LEFT", "star", "`repository`.id=`star`.repo_id")
+ if !private {
+ sess = sess.And("is_private=?", false)
+ }
+ repos := make([]*Repository, 0, 10)
+ err := sess.Find(&repos)
+ if err != nil {
+ return nil, err
+ }
+ return repos, nil
+}
diff --git a/modules/context/api.go b/modules/context/api.go
index 197fbd6df1..0da1823797 100644
--- a/modules/context/api.go
+++ b/modules/context/api.go
@@ -8,6 +8,7 @@ import (
"fmt"
"strings"
+ "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
@@ -70,3 +71,33 @@ func APIContexter() macaron.Handler {
c.Map(ctx)
}
}
+
+// ExtractOwnerAndRepo returns a handler that populates the `Repo.Owner` and
+// `Repo.Repository` fields of an APIContext
+func ExtractOwnerAndRepo() macaron.Handler {
+ return func(ctx *APIContext) {
+ owner, err := models.GetUserByName(ctx.Params(":username"))
+ if err != nil {
+ if models.IsErrUserNotExist(err) {
+ ctx.Error(422, "", err)
+ } else {
+ ctx.Error(500, "GetUserByName", err)
+ }
+ return
+ }
+
+ repo, err := models.GetRepositoryByName(owner.ID, ctx.Params(":reponame"))
+ if err != nil {
+ if models.IsErrRepoNotExist(err) {
+ ctx.Status(404)
+ } else {
+ ctx.Error(500, "GetRepositoryByName", err)
+ }
+ return
+ }
+ ctx.Repo.Owner = owner
+ ctx.Data["Owner"] = owner
+ ctx.Repo.Repository = repo
+ ctx.Data["Repository"] = repo
+ }
+}
diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go
index 08fc2c75e6..95bdfd072e 100644
--- a/routers/api/v1/api.go
+++ b/routers/api/v1/api.go
@@ -200,6 +200,8 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get("", user.ListFollowing)
m.Get("/:target", user.CheckFollowing)
})
+
+ m.Get("/starred", user.GetStarredRepos)
})
}, reqToken())
@@ -221,6 +223,15 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Combo("/:id").Get(user.GetPublicKey).
Delete(user.DeletePublicKey)
})
+
+ m.Group("/starred", func() {
+ m.Get("", user.GetMyStarredRepos)
+ m.Group("/:username/:reponame", func() {
+ m.Get("", user.IsStarring)
+ m.Put("", user.Star)
+ m.Delete("", user.Unstar)
+ }, context.ExtractOwnerAndRepo())
+ })
}, reqToken())
// Repositories
@@ -234,7 +245,8 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Group("/repos", func() {
m.Post("/migrate", bind(auth.MigrateRepoForm{}), repo.Migrate)
- m.Combo("/:username/:reponame").Get(repo.Get).
+ m.Combo("/:username/:reponame", context.ExtractOwnerAndRepo()).
+ Get(repo.Get).
Delete(repo.Delete)
m.Group("/:username/:reponame", func() {
diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go
index 02eb82d0fd..4353fb74ea 100644
--- a/routers/api/v1/repo/repo.go
+++ b/routers/api/v1/repo/repo.go
@@ -238,46 +238,16 @@ func Migrate(ctx *context.APIContext, form auth.MigrateRepoForm) {
ctx.JSON(201, repo.APIFormat(&api.Permission{true, true, true}))
}
-func parseOwnerAndRepo(ctx *context.APIContext) (*models.User, *models.Repository) {
- owner, err := models.GetUserByName(ctx.Params(":username"))
- if err != nil {
- if models.IsErrUserNotExist(err) {
- ctx.Error(422, "", err)
- } else {
- ctx.Error(500, "GetUserByName", err)
- }
- return nil, nil
- }
-
- repo, err := models.GetRepositoryByName(owner.ID, ctx.Params(":reponame"))
- if err != nil {
- if models.IsErrRepoNotExist(err) {
- ctx.Status(404)
- } else {
- ctx.Error(500, "GetRepositoryByName", err)
- }
- return nil, nil
- }
-
- return owner, repo
-}
-
// https://github.com/gogits/go-gogs-client/wiki/Repositories#get
func Get(ctx *context.APIContext) {
- _, repo := parseOwnerAndRepo(ctx)
- if ctx.Written() {
- return
- }
-
+ repo := ctx.Repo.Repository
ctx.JSON(200, repo.APIFormat(&api.Permission{true, true, true}))
}
// https://github.com/gogits/go-gogs-client/wiki/Repositories#delete
func Delete(ctx *context.APIContext) {
- owner, repo := parseOwnerAndRepo(ctx)
- if ctx.Written() {
- return
- }
+ owner := ctx.Repo.Owner
+ repo := ctx.Repo.Repository
if owner.IsOrganization() && !owner.IsOwnedBy(ctx.User.ID) {
ctx.Error(403, "", "Given user is not owner of organization.")
diff --git a/routers/api/v1/user/star.go b/routers/api/v1/user/star.go
new file mode 100644
index 0000000000..c856ecefdd
--- /dev/null
+++ b/routers/api/v1/user/star.go
@@ -0,0 +1,76 @@
+// Copyright 2016 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package user
+
+import (
+ api "code.gitea.io/sdk/gitea"
+
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/modules/context"
+)
+
+// getStarredRepos returns the repos that the user with the specified userID has
+// starred
+func getStarredRepos(userID int64, private bool) ([]*api.Repository, error) {
+ starredRepos, err := models.GetStarredRepos(userID, private)
+ if err != nil {
+ return nil, err
+ }
+ repos := make([]*api.Repository, len(starredRepos))
+ for i, starred := range starredRepos {
+ repos[i] = starred.APIFormat(&api.Permission{true, true, true})
+ }
+ return repos, nil
+}
+
+// GetStarredRepos returns the repos that the user specified by the APIContext
+// has starred
+func GetStarredRepos(ctx *context.APIContext) {
+ user := GetUserByParams(ctx)
+ private := user.ID == ctx.User.ID
+ repos, err := getStarredRepos(user.ID, private)
+ if err != nil {
+ ctx.Error(500, "getStarredRepos", err)
+ }
+ ctx.JSON(200, &repos)
+}
+
+// GetMyStarredRepos returns the repos that the authenticated user has starred
+func GetMyStarredRepos(ctx *context.APIContext) {
+ repos, err := getStarredRepos(ctx.User.ID, true)
+ if err != nil {
+ ctx.Error(500, "getStarredRepos", err)
+ }
+ ctx.JSON(200, &repos)
+}
+
+// IsStarring returns whether the authenticated is starring the repo
+func IsStarring(ctx *context.APIContext) {
+ if models.IsStaring(ctx.User.ID, ctx.Repo.Repository.ID) {
+ ctx.Status(204)
+ } else {
+ ctx.Status(404)
+ }
+}
+
+// Star the repo specified in the APIContext, as the authenticated user
+func Star(ctx *context.APIContext) {
+ err := models.StarRepo(ctx.User.ID, ctx.Repo.Repository.ID, true)
+ if err != nil {
+ ctx.Error(500, "StarRepo", err)
+ return
+ }
+ ctx.Status(204)
+}
+
+// Unstar the repo specified in the APIContext, as the authenticated user
+func Unstar(ctx *context.APIContext) {
+ err := models.StarRepo(ctx.User.ID, ctx.Repo.Repository.ID, false)
+ if err != nil {
+ ctx.Error(500, "StarRepo", err)
+ return
+ }
+ ctx.Status(204)
+}