2014-07-26 08:24:27 +04:00
// Copyright 2014 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 repo
import (
"bytes"
"io/ioutil"
"path"
"strings"
2015-11-17 07:28:46 +03:00
"github.com/Unknwon/paginater"
2015-12-16 01:25:45 +03:00
"github.com/gogits/git-module"
2015-12-10 04:46:05 +03:00
2014-09-26 16:55:13 +04:00
"github.com/gogits/gogs/models"
2014-07-26 08:24:27 +04:00
"github.com/gogits/gogs/modules/base"
2016-03-11 19:56:52 +03:00
"github.com/gogits/gogs/modules/context"
2014-08-23 16:30:29 +04:00
"github.com/gogits/gogs/modules/log"
2016-02-21 01:10:05 +03:00
"github.com/gogits/gogs/modules/markdown"
2016-07-12 01:21:26 +03:00
"github.com/gogits/gogs/modules/setting"
2015-11-14 01:10:25 +03:00
"github.com/gogits/gogs/modules/template"
2016-01-31 19:19:02 +03:00
"github.com/gogits/gogs/modules/template/highlight"
2014-07-26 08:24:27 +04:00
)
const (
2015-11-17 07:28:46 +03:00
HOME base . TplName = "repo/home"
WATCHERS base . TplName = "repo/watchers"
2015-11-17 07:33:40 +03:00
FORKS base . TplName = "repo/forks"
2014-07-26 08:24:27 +04:00
)
2016-03-11 19:56:52 +03:00
func Home ( ctx * context . Context ) {
2016-06-27 11:38:35 +03:00
title := ctx . Repo . Repository . Owner . Name + "/" + ctx . Repo . Repository . Name
if len ( ctx . Repo . Repository . Description ) > 0 {
title += ": " + ctx . Repo . Repository . Description
}
ctx . Data [ "Title" ] = title
2015-11-26 04:10:25 +03:00
ctx . Data [ "PageIsViewCode" ] = true
2015-11-14 12:34:01 +03:00
ctx . Data [ "RequireHighlightJS" ] = true
2014-07-26 08:24:27 +04:00
branchName := ctx . Repo . BranchName
userName := ctx . Repo . Owner . Name
repoName := ctx . Repo . Repository . Name
repoLink := ctx . Repo . RepoLink
branchLink := ctx . Repo . RepoLink + "/src/" + branchName
2015-11-09 10:13:25 +03:00
treeLink := branchLink
2014-07-26 08:24:27 +04:00
rawLink := ctx . Repo . RepoLink + "/raw/" + branchName
// Get tree path
2014-11-07 06:06:41 +03:00
treename := ctx . Repo . TreeName
2014-07-26 08:24:27 +04:00
2015-11-09 10:13:25 +03:00
if len ( treename ) > 0 {
if treename [ len ( treename ) - 1 ] == '/' {
ctx . Redirect ( repoLink + "/src/" + branchName + "/" + treename [ : len ( treename ) - 1 ] )
return
}
treeLink += "/" + treename
2014-07-26 08:24:27 +04:00
}
treePath := treename
if len ( treePath ) != 0 {
treePath = treePath + "/"
}
entry , err := ctx . Repo . Commit . GetTreeEntryByPath ( treename )
2015-12-10 04:46:05 +03:00
if err != nil && git . IsErrNotExist ( err ) {
2014-07-26 08:24:27 +04:00
ctx . Handle ( 404 , "GetTreeEntryByPath" , err )
return
}
if len ( treename ) != 0 && entry == nil {
ctx . Handle ( 404 , "repo.Home" , nil )
return
}
if entry != nil && ! entry . IsDir ( ) {
blob := entry . Blob ( )
if dataRc , err := blob . Data ( ) ; err != nil {
ctx . Handle ( 404 , "blob.Data" , err )
return
} else {
ctx . Data [ "FileSize" ] = blob . Size ( )
ctx . Data [ "IsFile" ] = true
ctx . Data [ "FileName" ] = blob . Name ( )
2016-01-31 19:19:02 +03:00
ctx . Data [ "HighlightClass" ] = highlight . FileNameToHighlightClass ( blob . Name ( ) )
2014-07-26 08:24:27 +04:00
ctx . Data [ "FileLink" ] = rawLink + "/" + treename
buf := make ( [ ] byte , 1024 )
n , _ := dataRc . Read ( buf )
if n > 0 {
buf = buf [ : n ]
}
_ , isTextFile := base . IsTextFile ( buf )
_ , isImageFile := base . IsImageFile ( buf )
2016-04-27 04:48:44 +03:00
_ , isPDFFile := base . IsPDFFile ( buf )
2014-07-26 08:24:27 +04:00
ctx . Data [ "IsFileText" ] = isTextFile
switch {
2016-04-27 04:48:44 +03:00
case isPDFFile :
ctx . Data [ "IsPDFFile" ] = true
2014-07-26 08:24:27 +04:00
case isImageFile :
ctx . Data [ "IsImageFile" ] = true
case isTextFile :
2016-07-12 01:21:26 +03:00
if blob . Size ( ) >= setting . MaxDisplayFileSize {
ctx . Data [ "IsFileTooLarge" ] = true
2014-07-26 08:24:27 +04:00
} else {
2016-07-12 01:21:26 +03:00
ctx . Data [ "IsFileTooLarge" ] = false
d , _ := ioutil . ReadAll ( dataRc )
buf = append ( buf , d ... )
readmeExist := markdown . IsMarkdownFile ( blob . Name ( ) ) || markdown . IsReadmeFile ( blob . Name ( ) )
ctx . Data [ "ReadmeExist" ] = readmeExist
if readmeExist {
ctx . Data [ "FileContent" ] = string ( markdown . Render ( buf , path . Dir ( treeLink ) , ctx . Repo . Repository . ComposeMetas ( ) ) )
2014-08-20 12:34:48 +04:00
} else {
2016-07-12 01:21:26 +03:00
if err , content := template . ToUtf8WithErr ( buf ) ; err != nil {
if err != nil {
log . Error ( 4 , "Convert content encoding: %s" , err )
}
ctx . Data [ "FileContent" ] = string ( buf )
} else {
ctx . Data [ "FileContent" ] = content
}
2014-08-20 12:34:48 +04:00
}
2014-07-26 08:24:27 +04:00
}
}
}
} else {
// Directory and file list.
tree , err := ctx . Repo . Commit . SubTree ( treename )
if err != nil {
ctx . Handle ( 404 , "SubTree" , err )
return
}
2014-09-30 12:39:53 +04:00
2015-12-10 04:46:05 +03:00
entries , err := tree . ListEntries ( )
2014-07-26 08:24:27 +04:00
if err != nil {
ctx . Handle ( 500 , "ListEntries" , err )
return
}
entries . Sort ( )
2015-12-14 06:58:12 +03:00
ctx . Data [ "Files" ] , err = entries . GetCommitsInfo ( ctx . Repo . Commit , treePath )
if err != nil {
ctx . Handle ( 500 , "GetCommitsInfo" , err )
return
2014-07-26 08:24:27 +04:00
}
var readmeFile * git . Blob
for _ , f := range entries {
2016-02-21 01:10:05 +03:00
if f . IsDir ( ) || ! markdown . IsReadmeFile ( f . Name ( ) ) {
2014-07-26 08:24:27 +04:00
continue
} else {
readmeFile = f . Blob ( )
break
}
}
if readmeFile != nil {
2014-10-12 02:02:48 +04:00
ctx . Data [ "ReadmeInList" ] = true
2014-07-26 08:24:27 +04:00
ctx . Data [ "ReadmeExist" ] = true
if dataRc , err := readmeFile . Data ( ) ; err != nil {
2015-11-22 05:09:18 +03:00
ctx . Handle ( 404 , "repo.SinglereadmeFile.Data" , err )
2014-07-26 08:24:27 +04:00
return
} else {
buf := make ( [ ] byte , 1024 )
n , _ := dataRc . Read ( buf )
if n > 0 {
buf = buf [ : n ]
}
ctx . Data [ "FileSize" ] = readmeFile . Size ( )
ctx . Data [ "FileLink" ] = rawLink + "/" + treename
_ , isTextFile := base . IsTextFile ( buf )
ctx . Data [ "FileIsText" ] = isTextFile
ctx . Data [ "FileName" ] = readmeFile . Name ( )
if isTextFile {
d , _ := ioutil . ReadAll ( dataRc )
buf = append ( buf , d ... )
switch {
2016-02-21 01:10:05 +03:00
case markdown . IsMarkdownFile ( readmeFile . Name ( ) ) :
buf = markdown . Render ( buf , treeLink , ctx . Repo . Repository . ComposeMetas ( ) )
2014-07-26 08:24:27 +04:00
default :
buf = bytes . Replace ( buf , [ ] byte ( "\n" ) , [ ] byte ( ` <br> ` ) , - 1 )
}
ctx . Data [ "FileContent" ] = string ( buf )
}
}
}
2014-09-26 16:55:13 +04:00
lastCommit := ctx . Repo . Commit
if len ( treePath ) > 0 {
2015-12-10 04:46:05 +03:00
c , err := ctx . Repo . Commit . GetCommitByPath ( treePath )
2014-09-26 16:55:13 +04:00
if err != nil {
2015-12-10 04:46:05 +03:00
ctx . Handle ( 500 , "GetCommitByPath" , err )
2014-09-26 16:55:13 +04:00
return
}
lastCommit = c
}
ctx . Data [ "LastCommit" ] = lastCommit
ctx . Data [ "LastCommitUser" ] = models . ValidateCommitWithEmail ( lastCommit )
2014-07-26 08:24:27 +04:00
}
ctx . Data [ "Username" ] = userName
ctx . Data [ "Reponame" ] = repoName
var treenames [ ] string
Paths := make ( [ ] string , 0 )
if len ( treename ) > 0 {
treenames = strings . Split ( treename , "/" )
for i , _ := range treenames {
Paths = append ( Paths , strings . Join ( treenames [ 0 : i + 1 ] , "/" ) )
}
ctx . Data [ "HasParentPath" ] = true
if len ( Paths ) - 2 >= 0 {
ctx . Data [ "ParentPath" ] = "/" + Paths [ len ( Paths ) - 2 ]
}
}
ctx . Data [ "Paths" ] = Paths
ctx . Data [ "TreeName" ] = treename
ctx . Data [ "Treenames" ] = treenames
ctx . Data [ "TreePath" ] = treePath
ctx . Data [ "BranchLink" ] = branchLink
ctx . HTML ( 200 , HOME )
}
2015-11-17 07:28:46 +03:00
2016-03-11 19:56:52 +03:00
func RenderUserCards ( ctx * context . Context , total int , getter func ( page int ) ( [ ] * models . User , error ) , tpl base . TplName ) {
2015-11-17 07:28:46 +03:00
page := ctx . QueryInt ( "page" )
if page <= 0 {
page = 1
}
pager := paginater . New ( total , models . ItemsPerPage , page , 5 )
ctx . Data [ "Page" ] = pager
items , err := getter ( pager . Current ( ) )
if err != nil {
ctx . Handle ( 500 , "getter" , err )
return
}
2015-12-21 15:24:11 +03:00
ctx . Data [ "Cards" ] = items
2015-11-17 07:28:46 +03:00
2015-12-21 15:24:11 +03:00
ctx . HTML ( 200 , tpl )
2015-11-17 07:28:46 +03:00
}
2016-03-11 19:56:52 +03:00
func Watchers ( ctx * context . Context ) {
2015-11-17 07:28:46 +03:00
ctx . Data [ "Title" ] = ctx . Tr ( "repo.watchers" )
2015-12-21 15:24:11 +03:00
ctx . Data [ "CardsTitle" ] = ctx . Tr ( "repo.watchers" )
2015-11-17 07:28:46 +03:00
ctx . Data [ "PageIsWatchers" ] = true
2015-12-21 15:24:11 +03:00
RenderUserCards ( ctx , ctx . Repo . Repository . NumWatches , ctx . Repo . Repository . GetWatchers , WATCHERS )
2015-11-17 07:28:46 +03:00
}
2016-03-11 19:56:52 +03:00
func Stars ( ctx * context . Context ) {
2015-11-17 07:28:46 +03:00
ctx . Data [ "Title" ] = ctx . Tr ( "repo.stargazers" )
2015-12-21 15:24:11 +03:00
ctx . Data [ "CardsTitle" ] = ctx . Tr ( "repo.stargazers" )
2015-11-17 07:28:46 +03:00
ctx . Data [ "PageIsStargazers" ] = true
2015-12-21 15:24:11 +03:00
RenderUserCards ( ctx , ctx . Repo . Repository . NumStars , ctx . Repo . Repository . GetStargazers , WATCHERS )
2015-11-17 07:28:46 +03:00
}
2015-11-17 07:33:40 +03:00
2016-03-11 19:56:52 +03:00
func Forks ( ctx * context . Context ) {
2015-11-17 07:33:40 +03:00
ctx . Data [ "Title" ] = ctx . Tr ( "repos.forks" )
forks , err := ctx . Repo . Repository . GetForks ( )
if err != nil {
ctx . Handle ( 500 , "GetForks" , err )
return
}
for _ , fork := range forks {
if err = fork . GetOwner ( ) ; err != nil {
ctx . Handle ( 500 , "GetOwner" , err )
return
}
}
ctx . Data [ "Forks" ] = forks
ctx . HTML ( 200 , FORKS )
}