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  }