| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 | // 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 contextimport (	"fmt"	"net/http"	"strings"	"github.com/unknwon/paginater"	"gopkg.in/macaron.v1"	log "unknwon.dev/clog/v2"	"gogs.io/gogs/internal/conf"	"gogs.io/gogs/internal/errutil")type APIContext struct {	*Context // TODO: Reduce to only needed fields instead of full shadow	// Base URL for the version of API endpoints, e.g. https://try.gogs.io/api/v1	BaseURL string	Org *APIOrganization}// FIXME: move this constant to github.com/gogs/go-gogs-clientconst DocURL = "https://github.com/gogs/docs-api"// NoContent renders the 204 response.func (c *APIContext) NoContent() {	c.Status(http.StatusNoContent)}// NotFound renders the 404 response.func (c *APIContext) NotFound() {	c.Status(http.StatusNotFound)}// ErrorStatus renders error with given status code.func (c *APIContext) ErrorStatus(status int, err error) {	c.JSON(status, map[string]string{		"message": err.Error(),		"url":     DocURL,	})}// Error renders the 500 response.func (c *APIContext) Error(err error, msg string) {	log.ErrorDepth(5, "%s: %v", msg, err)	c.ErrorStatus(http.StatusInternalServerError, err)}// Errorf renders the 500 response with formatted message.func (c *APIContext) Errorf(err error, format string, args ...interface{}) {	c.Error(err, fmt.Sprintf(format, args...))}// NotFoundOrError use error check function to determine if the error// is about not found. It responses with 404 status code for not found error,// or error context description for logging purpose of 500 server error.func (c *APIContext) NotFoundOrError(err error, msg string) {	if errutil.IsNotFound(err) {		c.NotFound()		return	}	c.Error(err, msg)}// SetLinkHeader sets pagination link header by given total number and page size.func (c *APIContext) SetLinkHeader(total, pageSize int) {	page := paginater.New(total, pageSize, c.QueryInt("page"), 0)	links := make([]string, 0, 4)	if page.HasNext() {		links = append(links, fmt.Sprintf("<%s%s?page=%d>; rel=\"next\"", conf.Server.ExternalURL, c.Req.URL.Path[1:], page.Next()))	}	if !page.IsLast() {		links = append(links, fmt.Sprintf("<%s%s?page=%d>; rel=\"last\"", conf.Server.ExternalURL, c.Req.URL.Path[1:], page.TotalPages()))	}	if !page.IsFirst() {		links = append(links, fmt.Sprintf("<%s%s?page=1>; rel=\"first\"", conf.Server.ExternalURL, c.Req.URL.Path[1:]))	}	if page.HasPrevious() {		links = append(links, fmt.Sprintf("<%s%s?page=%d>; rel=\"prev\"", conf.Server.ExternalURL, c.Req.URL.Path[1:], page.Previous()))	}	if len(links) > 0 {		c.Header().Set("Link", strings.Join(links, ","))	}}func APIContexter() macaron.Handler {	return func(ctx *Context) {		c := &APIContext{			Context: ctx,			BaseURL: conf.Server.ExternalURL + "api/v1",		}		ctx.Map(c)	}}
 |