code.gitea.io/gitea@v1.21.7/routers/api/v1/user/watch.go (about) 1 // Copyright 2016 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package user 5 6 import ( 7 std_context "context" 8 "net/http" 9 10 "code.gitea.io/gitea/models/db" 11 access_model "code.gitea.io/gitea/models/perm/access" 12 repo_model "code.gitea.io/gitea/models/repo" 13 user_model "code.gitea.io/gitea/models/user" 14 "code.gitea.io/gitea/modules/context" 15 api "code.gitea.io/gitea/modules/structs" 16 "code.gitea.io/gitea/routers/api/v1/utils" 17 "code.gitea.io/gitea/services/convert" 18 ) 19 20 // getWatchedRepos returns the repos that the user with the specified userID is watching 21 func getWatchedRepos(ctx std_context.Context, user *user_model.User, private bool, listOptions db.ListOptions) ([]*api.Repository, int64, error) { 22 watchedRepos, total, err := repo_model.GetWatchedRepos(ctx, user.ID, private, listOptions) 23 if err != nil { 24 return nil, 0, err 25 } 26 27 repos := make([]*api.Repository, len(watchedRepos)) 28 for i, watched := range watchedRepos { 29 permission, err := access_model.GetUserRepoPermission(ctx, watched, user) 30 if err != nil { 31 return nil, 0, err 32 } 33 repos[i] = convert.ToRepo(ctx, watched, permission) 34 } 35 return repos, total, nil 36 } 37 38 // GetWatchedRepos returns the repos that the user specified in ctx is watching 39 func GetWatchedRepos(ctx *context.APIContext) { 40 // swagger:operation GET /users/{username}/subscriptions user userListSubscriptions 41 // --- 42 // summary: List the repositories watched by a user 43 // produces: 44 // - application/json 45 // parameters: 46 // - name: username 47 // type: string 48 // in: path 49 // description: username of the user 50 // required: true 51 // - name: page 52 // in: query 53 // description: page number of results to return (1-based) 54 // type: integer 55 // - name: limit 56 // in: query 57 // description: page size of results 58 // type: integer 59 // responses: 60 // "200": 61 // "$ref": "#/responses/RepositoryList" 62 // "404": 63 // "$ref": "#/responses/notFound" 64 65 private := ctx.ContextUser.ID == ctx.Doer.ID 66 repos, total, err := getWatchedRepos(ctx, ctx.ContextUser, private, utils.GetListOptions(ctx)) 67 if err != nil { 68 ctx.Error(http.StatusInternalServerError, "getWatchedRepos", err) 69 } 70 71 ctx.SetTotalCountHeader(total) 72 ctx.JSON(http.StatusOK, &repos) 73 } 74 75 // GetMyWatchedRepos returns the repos that the authenticated user is watching 76 func GetMyWatchedRepos(ctx *context.APIContext) { 77 // swagger:operation GET /user/subscriptions user userCurrentListSubscriptions 78 // --- 79 // summary: List repositories watched by the authenticated user 80 // produces: 81 // - application/json 82 // parameters: 83 // - name: page 84 // in: query 85 // description: page number of results to return (1-based) 86 // type: integer 87 // - name: limit 88 // in: query 89 // description: page size of results 90 // type: integer 91 // responses: 92 // "200": 93 // "$ref": "#/responses/RepositoryList" 94 95 repos, total, err := getWatchedRepos(ctx, ctx.Doer, true, utils.GetListOptions(ctx)) 96 if err != nil { 97 ctx.Error(http.StatusInternalServerError, "getWatchedRepos", err) 98 } 99 100 ctx.SetTotalCountHeader(total) 101 ctx.JSON(http.StatusOK, &repos) 102 } 103 104 // IsWatching returns whether the authenticated user is watching the repo 105 // specified in ctx 106 func IsWatching(ctx *context.APIContext) { 107 // swagger:operation GET /repos/{owner}/{repo}/subscription repository userCurrentCheckSubscription 108 // --- 109 // summary: Check if the current user is watching a repo 110 // parameters: 111 // - name: owner 112 // in: path 113 // description: owner of the repo 114 // type: string 115 // required: true 116 // - name: repo 117 // in: path 118 // description: name of the repo 119 // type: string 120 // required: true 121 // responses: 122 // "200": 123 // "$ref": "#/responses/WatchInfo" 124 // "404": 125 // description: User is not watching this repo or repo do not exist 126 127 if repo_model.IsWatching(ctx, ctx.Doer.ID, ctx.Repo.Repository.ID) { 128 ctx.JSON(http.StatusOK, api.WatchInfo{ 129 Subscribed: true, 130 Ignored: false, 131 Reason: nil, 132 CreatedAt: ctx.Repo.Repository.CreatedUnix.AsTime(), 133 URL: subscriptionURL(ctx.Repo.Repository), 134 RepositoryURL: ctx.Repo.Repository.APIURL(), 135 }) 136 } else { 137 ctx.NotFound() 138 } 139 } 140 141 // Watch the repo specified in ctx, as the authenticated user 142 func Watch(ctx *context.APIContext) { 143 // swagger:operation PUT /repos/{owner}/{repo}/subscription repository userCurrentPutSubscription 144 // --- 145 // summary: Watch a repo 146 // parameters: 147 // - name: owner 148 // in: path 149 // description: owner of the repo 150 // type: string 151 // required: true 152 // - name: repo 153 // in: path 154 // description: name of the repo 155 // type: string 156 // required: true 157 // responses: 158 // "200": 159 // "$ref": "#/responses/WatchInfo" 160 // "404": 161 // "$ref": "#/responses/notFound" 162 163 err := repo_model.WatchRepo(ctx, ctx.Doer.ID, ctx.Repo.Repository.ID, true) 164 if err != nil { 165 ctx.Error(http.StatusInternalServerError, "WatchRepo", err) 166 return 167 } 168 ctx.JSON(http.StatusOK, api.WatchInfo{ 169 Subscribed: true, 170 Ignored: false, 171 Reason: nil, 172 CreatedAt: ctx.Repo.Repository.CreatedUnix.AsTime(), 173 URL: subscriptionURL(ctx.Repo.Repository), 174 RepositoryURL: ctx.Repo.Repository.APIURL(), 175 }) 176 } 177 178 // Unwatch the repo specified in ctx, as the authenticated user 179 func Unwatch(ctx *context.APIContext) { 180 // swagger:operation DELETE /repos/{owner}/{repo}/subscription repository userCurrentDeleteSubscription 181 // --- 182 // summary: Unwatch a repo 183 // parameters: 184 // - name: owner 185 // in: path 186 // description: owner of the repo 187 // type: string 188 // required: true 189 // - name: repo 190 // in: path 191 // description: name of the repo 192 // type: string 193 // required: true 194 // responses: 195 // "204": 196 // "$ref": "#/responses/empty" 197 // "404": 198 // "$ref": "#/responses/notFound" 199 200 err := repo_model.WatchRepo(ctx, ctx.Doer.ID, ctx.Repo.Repository.ID, false) 201 if err != nil { 202 ctx.Error(http.StatusInternalServerError, "UnwatchRepo", err) 203 return 204 } 205 ctx.Status(http.StatusNoContent) 206 } 207 208 // subscriptionURL returns the URL of the subscription API endpoint of a repo 209 func subscriptionURL(repo *repo_model.Repository) string { 210 return repo.APIURL() + "/subscription" 211 }