2016-03-14 00:37:44 +03:00
// 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 context
import (
2016-03-14 06:20:22 +03:00
"fmt"
"strings"
2016-12-02 14:10:39 +03:00
"code.gitea.io/git"
2016-11-15 01:33:58 +03:00
"code.gitea.io/gitea/models"
2016-11-10 19:24:48 +03:00
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
2016-11-11 15:11:45 +03:00
"github.com/Unknwon/paginater"
2016-11-05 19:56:35 +03:00
macaron "gopkg.in/macaron.v1"
2016-03-14 00:37:44 +03:00
)
2016-11-25 09:51:01 +03:00
// APIContext is a specific macaron context for API service
2016-03-14 00:37:44 +03:00
type APIContext struct {
* Context
2016-03-26 01:04:02 +03:00
Org * APIOrganization
2016-03-14 00:37:44 +03:00
}
2016-03-14 01:49:16 +03:00
// Error responses error message to client with given message.
// If status is 500, also it prints error to log.
func ( ctx * APIContext ) Error ( status int , title string , obj interface { } ) {
var message string
if err , ok := obj . ( error ) ; ok {
message = err . Error ( )
} else {
message = obj . ( string )
}
if status == 500 {
log . Error ( 4 , "%s: %s" , title , message )
}
ctx . JSON ( status , map [ string ] string {
"message" : message ,
2016-11-07 12:07:43 +03:00
"url" : base . DocURL ,
2016-03-14 01:49:16 +03:00
} )
}
2016-03-26 01:04:02 +03:00
// SetLinkHeader sets pagination link header by given totol number and page size.
2016-03-14 06:20:22 +03:00
func ( ctx * APIContext ) SetLinkHeader ( total , pageSize int ) {
page := paginater . New ( total , pageSize , ctx . QueryInt ( "page" ) , 0 )
links := make ( [ ] string , 0 , 4 )
if page . HasNext ( ) {
2016-11-27 13:14:25 +03:00
links = append ( links , fmt . Sprintf ( "<%s%s?page=%d>; rel=\"next\"" , setting . AppURL , ctx . Req . URL . Path [ 1 : ] , page . Next ( ) ) )
2016-03-14 06:20:22 +03:00
}
if ! page . IsLast ( ) {
2016-11-27 13:14:25 +03:00
links = append ( links , fmt . Sprintf ( "<%s%s?page=%d>; rel=\"last\"" , setting . AppURL , ctx . Req . URL . Path [ 1 : ] , page . TotalPages ( ) ) )
2016-03-14 06:20:22 +03:00
}
if ! page . IsFirst ( ) {
2016-11-27 13:14:25 +03:00
links = append ( links , fmt . Sprintf ( "<%s%s?page=1>; rel=\"first\"" , setting . AppURL , ctx . Req . URL . Path [ 1 : ] ) )
2016-03-14 06:20:22 +03:00
}
if page . HasPrevious ( ) {
2016-11-27 13:14:25 +03:00
links = append ( links , fmt . Sprintf ( "<%s%s?page=%d>; rel=\"prev\"" , setting . AppURL , ctx . Req . URL . Path [ 1 : ] , page . Previous ( ) ) )
2016-03-14 06:20:22 +03:00
}
if len ( links ) > 0 {
ctx . Header ( ) . Set ( "Link" , strings . Join ( links , "," ) )
}
}
2016-11-25 09:51:01 +03:00
// APIContexter returns apicontext as macaron middleware
2016-03-14 00:37:44 +03:00
func APIContexter ( ) macaron . Handler {
return func ( c * Context ) {
ctx := & APIContext {
Context : c ,
}
c . Map ( ctx )
}
}
2016-11-15 01:33:58 +03:00
2016-12-02 14:10:39 +03:00
// ReferencesGitRepo injects the GitRepo into the Context
func ReferencesGitRepo ( ) macaron . Handler {
return func ( ctx * APIContext ) {
// Empty repository does not have reference information.
if ctx . Repo . Repository . IsBare {
return
}
// For API calls.
if ctx . Repo . GitRepo == nil {
repoPath := models . RepoPath ( ctx . Repo . Owner . Name , ctx . Repo . Repository . Name )
gitRepo , err := git . OpenRepository ( repoPath )
if err != nil {
ctx . Error ( 500 , "RepoRef Invalid repo " + repoPath , err )
return
}
ctx . Repo . GitRepo = gitRepo
}
}
}