2016-08-11 15:48:08 +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 repo
import (
2016-08-30 15:07:50 +03:00
"fmt"
2016-08-11 15:48:08 +03:00
"io/ioutil"
2016-08-30 15:07:50 +03:00
"net/http"
2016-08-11 15:48:08 +03:00
"path"
"strings"
2016-11-11 15:11:45 +03:00
"code.gitea.io/git"
2016-11-10 19:24:48 +03:00
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/auth"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
2016-12-06 20:58:31 +03:00
"code.gitea.io/gitea/modules/templates"
2016-08-11 15:48:08 +03:00
)
const (
2016-11-24 10:04:31 +03:00
tplEditFile base . TplName = "repo/editor/edit"
tplEditDiffPreview base . TplName = "repo/editor/diff_preview"
tplDeleteFile base . TplName = "repo/editor/delete"
tplUploadFile base . TplName = "repo/editor/upload"
2017-05-02 03:49:55 +03:00
frmCommitChoiceDirect string = "direct"
frmCommitChoiceNewBranch string = "commit-to-new-branch"
2016-08-11 15:48:08 +03:00
)
2017-05-02 03:49:55 +03:00
func renderCommitRights ( ctx * context . Context ) bool {
2017-09-14 11:16:22 +03:00
canCommit , err := ctx . Repo . CanCommitToBranch ( ctx . User )
2017-05-02 03:49:55 +03:00
if err != nil {
log . Error ( 4 , "CanCommitToBranch: %v" , err )
}
ctx . Data [ "CanCommitToBranch" ] = canCommit
return canCommit
}
2017-06-22 18:30:47 +03:00
// getParentTreeFields returns list of parent tree names and corresponding tree paths
// based on given tree path.
func getParentTreeFields ( treePath string ) ( treeNames [ ] string , treePaths [ ] string ) {
if len ( treePath ) == 0 {
return treeNames , treePaths
}
treeNames = strings . Split ( treePath , "/" )
treePaths = make ( [ ] string , len ( treeNames ) )
for i := range treeNames {
treePaths [ i ] = strings . Join ( treeNames [ : i + 1 ] , "/" )
}
return treeNames , treePaths
}
2016-08-11 15:48:08 +03:00
func editFile ( ctx * context . Context , isNewFile bool ) {
ctx . Data [ "PageIsEdit" ] = true
ctx . Data [ "IsNewFile" ] = isNewFile
ctx . Data [ "RequireHighlightJS" ] = true
2016-08-15 09:02:14 +03:00
ctx . Data [ "RequireSimpleMDE" ] = true
2017-05-02 03:49:55 +03:00
canCommit := renderCommitRights ( ctx )
2016-08-11 15:48:08 +03:00
2017-06-22 18:30:47 +03:00
treeNames , treePaths := getParentTreeFields ( ctx . Repo . TreePath )
2016-08-11 15:48:08 +03:00
if ! isNewFile {
2016-08-25 07:35:03 +03:00
entry , err := ctx . Repo . Commit . GetTreeEntryByPath ( ctx . Repo . TreePath )
2016-08-15 09:02:14 +03:00
if err != nil {
2016-08-30 15:07:50 +03:00
ctx . NotFoundOrServerError ( "GetTreeEntryByPath" , git . IsErrNotExist , err )
2016-08-11 15:48:08 +03:00
return
}
2016-08-15 09:02:14 +03:00
// No way to edit a directory online.
if entry . IsDir ( ) {
ctx . Handle ( 404 , "" , nil )
2016-08-11 15:48:08 +03:00
return
}
blob := entry . Blob ( )
dataRc , err := blob . Data ( )
if err != nil {
ctx . Handle ( 404 , "blob.Data" , err )
return
}
ctx . Data [ "FileSize" ] = blob . Size ( )
ctx . Data [ "FileName" ] = blob . Name ( )
buf := make ( [ ] byte , 1024 )
n , _ := dataRc . Read ( buf )
2016-08-31 23:59:23 +03:00
buf = buf [ : n ]
2016-08-11 15:48:08 +03:00
2016-08-15 09:02:14 +03:00
// Only text file are editable online.
2016-08-30 12:08:38 +03:00
if ! base . IsTextFile ( buf ) {
2016-08-15 09:02:14 +03:00
ctx . Handle ( 404 , "" , nil )
2016-08-11 15:48:08 +03:00
return
}
d , _ := ioutil . ReadAll ( dataRc )
buf = append ( buf , d ... )
2016-12-06 20:58:31 +03:00
if content , err := templates . ToUTF8WithErr ( buf ) ; err != nil {
2016-08-11 15:48:08 +03:00
if err != nil {
2016-08-25 07:35:03 +03:00
log . Error ( 4 , "ToUTF8WithErr: %v" , err )
2016-08-11 15:48:08 +03:00
}
ctx . Data [ "FileContent" ] = string ( buf )
} else {
ctx . Data [ "FileContent" ] = content
}
} else {
2016-08-15 09:02:14 +03:00
treeNames = append ( treeNames , "" ) // Append empty string to allow user name the new file.
2016-08-11 15:48:08 +03:00
}
ctx . Data [ "TreeNames" ] = treeNames
2017-06-22 18:30:47 +03:00
ctx . Data [ "TreePaths" ] = treePaths
2017-10-30 05:04:25 +03:00
ctx . Data [ "BranchLink" ] = ctx . Repo . RepoLink + "/src/" + ctx . Repo . BranchNameSubURL ( )
2016-08-15 09:02:14 +03:00
ctx . Data [ "commit_summary" ] = ""
ctx . Data [ "commit_message" ] = ""
2017-05-02 03:49:55 +03:00
if canCommit {
ctx . Data [ "commit_choice" ] = frmCommitChoiceDirect
} else {
ctx . Data [ "commit_choice" ] = frmCommitChoiceNewBranch
}
2016-08-15 09:02:14 +03:00
ctx . Data [ "new_branch_name" ] = ""
ctx . Data [ "last_commit" ] = ctx . Repo . Commit . ID
2016-08-12 12:29:29 +03:00
ctx . Data [ "MarkdownFileExts" ] = strings . Join ( setting . Markdown . FileExtensions , "," )
ctx . Data [ "LineWrapExtensions" ] = strings . Join ( setting . Repository . Editor . LineWrapExtensions , "," )
ctx . Data [ "PreviewableFileModes" ] = strings . Join ( setting . Repository . Editor . PreviewableFileModes , "," )
2016-11-27 13:14:25 +03:00
ctx . Data [ "EditorconfigURLPrefix" ] = fmt . Sprintf ( "%s/api/v1/repos/%s/editorconfig/" , setting . AppSubURL , ctx . Repo . Repository . FullName ( ) )
2016-08-11 15:48:08 +03:00
2016-11-24 10:04:31 +03:00
ctx . HTML ( 200 , tplEditFile )
2016-08-11 15:48:08 +03:00
}
2016-11-24 10:04:31 +03:00
// EditFile render edit file page
2016-08-15 09:02:14 +03:00
func EditFile ( ctx * context . Context ) {
editFile ( ctx , false )
2016-08-11 15:48:08 +03:00
}
2016-11-24 10:04:31 +03:00
// NewFile render create file page
2016-08-15 09:02:14 +03:00
func NewFile ( ctx * context . Context ) {
editFile ( ctx , true )
2016-08-11 15:48:08 +03:00
}
func editFilePost ( ctx * context . Context , form auth . EditRepoFileForm , isNewFile bool ) {
ctx . Data [ "PageIsEdit" ] = true
ctx . Data [ "IsNewFile" ] = isNewFile
ctx . Data [ "RequireHighlightJS" ] = true
2016-08-15 09:02:14 +03:00
ctx . Data [ "RequireSimpleMDE" ] = true
2017-05-02 03:49:55 +03:00
canCommit := renderCommitRights ( ctx )
2016-08-11 15:48:08 +03:00
oldBranchName := ctx . Repo . BranchName
branchName := oldBranchName
2016-08-25 07:35:03 +03:00
oldTreePath := ctx . Repo . TreePath
2016-08-11 15:48:08 +03:00
lastCommit := form . LastCommit
2016-08-15 12:06:35 +03:00
form . LastCommit = ctx . Repo . Commit . ID . String ( )
2016-08-11 15:48:08 +03:00
2017-05-02 03:49:55 +03:00
if form . CommitChoice == frmCommitChoiceNewBranch {
2016-08-11 15:48:08 +03:00
branchName = form . NewBranchName
}
2016-08-25 07:35:03 +03:00
form . TreePath = strings . Trim ( form . TreePath , " /" )
2017-06-22 18:30:47 +03:00
treeNames , treePaths := getParentTreeFields ( form . TreePath )
2016-08-11 15:48:08 +03:00
2016-08-25 07:35:03 +03:00
ctx . Data [ "TreePath" ] = form . TreePath
2016-08-11 15:48:08 +03:00
ctx . Data [ "TreeNames" ] = treeNames
2017-06-22 18:30:47 +03:00
ctx . Data [ "TreePaths" ] = treePaths
2017-10-30 05:04:25 +03:00
ctx . Data [ "BranchLink" ] = ctx . Repo . RepoLink + "/src/branch/" + branchName
2016-08-28 11:41:44 +03:00
ctx . Data [ "FileContent" ] = form . Content
2016-08-15 09:02:14 +03:00
ctx . Data [ "commit_summary" ] = form . CommitSummary
ctx . Data [ "commit_message" ] = form . CommitMessage
2016-08-28 11:41:44 +03:00
ctx . Data [ "commit_choice" ] = form . CommitChoice
2016-08-15 09:02:14 +03:00
ctx . Data [ "new_branch_name" ] = branchName
2016-08-15 12:06:35 +03:00
ctx . Data [ "last_commit" ] = form . LastCommit
2016-08-12 12:29:29 +03:00
ctx . Data [ "MarkdownFileExts" ] = strings . Join ( setting . Markdown . FileExtensions , "," )
ctx . Data [ "LineWrapExtensions" ] = strings . Join ( setting . Repository . Editor . LineWrapExtensions , "," )
ctx . Data [ "PreviewableFileModes" ] = strings . Join ( setting . Repository . Editor . PreviewableFileModes , "," )
2016-08-11 15:48:08 +03:00
if ctx . HasError ( ) {
2016-11-24 10:04:31 +03:00
ctx . HTML ( 200 , tplEditFile )
2016-08-11 15:48:08 +03:00
return
}
2016-08-25 07:35:03 +03:00
if len ( form . TreePath ) == 0 {
ctx . Data [ "Err_TreePath" ] = true
2016-11-24 10:04:31 +03:00
ctx . RenderWithErr ( ctx . Tr ( "repo.editor.filename_cannot_be_empty" ) , tplEditFile , & form )
2016-08-11 15:48:08 +03:00
return
}
if oldBranchName != branchName {
if _ , err := ctx . Repo . Repository . GetBranch ( branchName ) ; err == nil {
2016-08-25 07:35:03 +03:00
ctx . Data [ "Err_NewBranchName" ] = true
2016-11-24 10:04:31 +03:00
ctx . RenderWithErr ( ctx . Tr ( "repo.editor.branch_already_exists" , branchName ) , tplEditFile , & form )
2016-08-11 15:48:08 +03:00
return
}
2017-05-02 03:49:55 +03:00
} else if ! canCommit {
ctx . Data [ "Err_NewBranchName" ] = true
ctx . Data [ "commit_choice" ] = frmCommitChoiceNewBranch
ctx . RenderWithErr ( ctx . Tr ( "repo.editor.cannot_commit_to_protected_branch" , branchName ) , tplEditFile , & form )
return
2016-08-11 15:48:08 +03:00
}
2016-08-25 07:35:03 +03:00
var newTreePath string
2016-08-11 15:48:08 +03:00
for index , part := range treeNames {
2016-08-25 07:35:03 +03:00
newTreePath = path . Join ( newTreePath , part )
entry , err := ctx . Repo . Commit . GetTreeEntryByPath ( newTreePath )
2016-08-11 15:48:08 +03:00
if err != nil {
2016-08-15 09:02:14 +03:00
if git . IsErrNotExist ( err ) {
// Means there is no item with that name, so we're good
break
}
2016-08-30 15:07:50 +03:00
ctx . Handle ( 500 , "Repo.Commit.GetTreeEntryByPath" , err )
2016-08-15 09:02:14 +03:00
return
2016-08-11 15:48:08 +03:00
}
if index != len ( treeNames ) - 1 {
if ! entry . IsDir ( ) {
2016-08-25 07:35:03 +03:00
ctx . Data [ "Err_TreePath" ] = true
2016-11-24 10:04:31 +03:00
ctx . RenderWithErr ( ctx . Tr ( "repo.editor.directory_is_a_file" , part ) , tplEditFile , & form )
2016-08-11 15:48:08 +03:00
return
}
} else {
2016-12-22 15:27:32 +03:00
if entry . IsLink ( ) {
ctx . Data [ "Err_TreePath" ] = true
ctx . RenderWithErr ( ctx . Tr ( "repo.editor.file_is_a_symlink" , part ) , tplEditFile , & form )
return
}
2016-08-11 15:48:08 +03:00
if entry . IsDir ( ) {
2016-08-25 07:35:03 +03:00
ctx . Data [ "Err_TreePath" ] = true
2016-11-24 10:04:31 +03:00
ctx . RenderWithErr ( ctx . Tr ( "repo.editor.filename_is_a_directory" , part ) , tplEditFile , & form )
2016-08-11 15:48:08 +03:00
return
}
}
}
if ! isNewFile {
2016-08-25 07:35:03 +03:00
_ , err := ctx . Repo . Commit . GetTreeEntryByPath ( oldTreePath )
2016-08-15 09:02:14 +03:00
if err != nil {
if git . IsErrNotExist ( err ) {
2016-08-25 07:35:03 +03:00
ctx . Data [ "Err_TreePath" ] = true
2016-11-24 10:04:31 +03:00
ctx . RenderWithErr ( ctx . Tr ( "repo.editor.file_editing_no_longer_exists" , oldTreePath ) , tplEditFile , & form )
2016-08-15 09:02:14 +03:00
} else {
ctx . Handle ( 500 , "GetTreeEntryByPath" , err )
}
2016-08-11 15:48:08 +03:00
return
}
if lastCommit != ctx . Repo . CommitID {
2016-08-15 09:02:14 +03:00
files , err := ctx . Repo . Commit . GetFilesChangedSinceCommit ( lastCommit )
if err != nil {
ctx . Handle ( 500 , "GetFilesChangedSinceCommit" , err )
return
}
for _ , file := range files {
2016-08-25 07:35:03 +03:00
if file == form . TreePath {
2016-11-24 10:04:31 +03:00
ctx . RenderWithErr ( ctx . Tr ( "repo.editor.file_changed_while_editing" , ctx . Repo . RepoLink + "/compare/" + lastCommit + "..." + ctx . Repo . CommitID ) , tplEditFile , & form )
2016-08-15 09:02:14 +03:00
return
2016-08-11 15:48:08 +03:00
}
}
}
}
2016-08-15 09:02:14 +03:00
2016-08-25 07:35:03 +03:00
if oldTreePath != form . TreePath {
2016-08-15 09:02:14 +03:00
// We have a new filename (rename or completely new file) so we need to make sure it doesn't already exist, can't clobber.
2016-08-25 07:35:03 +03:00
entry , err := ctx . Repo . Commit . GetTreeEntryByPath ( form . TreePath )
2016-08-15 09:02:14 +03:00
if err != nil {
if ! git . IsErrNotExist ( err ) {
ctx . Handle ( 500 , "GetTreeEntryByPath" , err )
return
}
}
if entry != nil {
2016-08-25 07:35:03 +03:00
ctx . Data [ "Err_TreePath" ] = true
2016-11-24 10:04:31 +03:00
ctx . RenderWithErr ( ctx . Tr ( "repo.editor.file_already_exists" , form . TreePath ) , tplEditFile , & form )
2016-08-11 15:48:08 +03:00
return
}
}
2016-08-28 11:41:44 +03:00
message := strings . TrimSpace ( form . CommitSummary )
if len ( message ) == 0 {
2016-08-11 15:48:08 +03:00
if isNewFile {
2016-08-25 07:35:03 +03:00
message = ctx . Tr ( "repo.editor.add" , form . TreePath )
2016-08-11 15:48:08 +03:00
} else {
2016-08-25 07:35:03 +03:00
message = ctx . Tr ( "repo.editor.update" , form . TreePath )
2016-08-11 15:48:08 +03:00
}
}
2016-08-15 09:02:14 +03:00
form . CommitMessage = strings . TrimSpace ( form . CommitMessage )
if len ( form . CommitMessage ) > 0 {
message += "\n\n" + form . CommitMessage
2016-08-11 15:48:08 +03:00
}
2016-08-16 08:20:55 +03:00
if err := ctx . Repo . Repository . UpdateRepoFile ( ctx . User , models . UpdateRepoFileOptions {
2016-08-15 09:02:14 +03:00
LastCommitID : lastCommit ,
OldBranch : oldBranchName ,
NewBranch : branchName ,
2016-08-25 07:35:03 +03:00
OldTreeName : oldTreePath ,
NewTreeName : form . TreePath ,
2016-08-15 09:02:14 +03:00
Message : message ,
2016-08-28 15:32:10 +03:00
Content : strings . Replace ( form . Content , "\r" , "" , - 1 ) ,
2016-08-15 09:02:14 +03:00
IsNewFile : isNewFile ,
} ) ; err != nil {
2016-08-25 07:35:03 +03:00
ctx . Data [ "Err_TreePath" ] = true
2016-11-24 10:04:31 +03:00
ctx . RenderWithErr ( ctx . Tr ( "repo.editor.fail_to_update_file" , form . TreePath , err ) , tplEditFile , & form )
2016-08-11 15:48:08 +03:00
return
}
2017-10-30 05:04:25 +03:00
ctx . Redirect ( ctx . Repo . RepoLink + "/src/branch/" + branchName + "/" + strings . NewReplacer ( "%" , "%25" , "#" , "%23" , " " , "%20" , "?" , "%3F" ) . Replace ( form . TreePath ) )
2016-08-15 09:02:14 +03:00
}
2016-08-11 15:48:08 +03:00
2016-11-24 10:04:31 +03:00
// EditFilePost response for editing file
2016-08-15 09:02:14 +03:00
func EditFilePost ( ctx * context . Context , form auth . EditRepoFileForm ) {
editFilePost ( ctx , form , false )
}
2016-11-24 10:04:31 +03:00
// NewFilePost response for creating file
2016-08-15 09:02:14 +03:00
func NewFilePost ( ctx * context . Context , form auth . EditRepoFileForm ) {
editFilePost ( ctx , form , true )
2016-08-11 15:48:08 +03:00
}
2016-11-24 10:04:31 +03:00
// DiffPreviewPost render preview diff page
2016-08-11 15:48:08 +03:00
func DiffPreviewPost ( ctx * context . Context , form auth . EditPreviewDiffForm ) {
2016-08-28 11:41:44 +03:00
treePath := ctx . Repo . TreePath
2016-08-11 15:48:08 +03:00
2016-08-28 11:41:44 +03:00
entry , err := ctx . Repo . Commit . GetTreeEntryByPath ( treePath )
2016-08-15 09:02:14 +03:00
if err != nil {
2016-08-28 14:31:42 +03:00
ctx . Error ( 500 , "GetTreeEntryByPath: " + err . Error ( ) )
2016-08-15 09:02:14 +03:00
return
2016-08-28 14:31:42 +03:00
} else if entry . IsDir ( ) {
2016-08-15 09:02:14 +03:00
ctx . Error ( 422 )
2016-08-11 15:48:08 +03:00
return
}
2016-08-28 15:32:10 +03:00
diff , err := ctx . Repo . Repository . GetDiffPreview ( ctx . Repo . BranchName , treePath , form . Content )
2016-08-11 15:48:08 +03:00
if err != nil {
2016-08-15 09:02:14 +03:00
ctx . Error ( 500 , "GetDiffPreview: " + err . Error ( ) )
2016-08-11 15:48:08 +03:00
return
}
if diff . NumFiles ( ) == 0 {
2016-08-15 09:02:14 +03:00
ctx . PlainText ( 200 , [ ] byte ( ctx . Tr ( "repo.editor.no_changes_to_show" ) ) )
2016-08-11 15:48:08 +03:00
return
}
ctx . Data [ "File" ] = diff . Files [ 0 ]
2016-11-24 10:04:31 +03:00
ctx . HTML ( 200 , tplEditDiffPreview )
2016-08-28 11:41:44 +03:00
}
2016-11-24 10:04:31 +03:00
// DeleteFile render delete file page
2016-08-28 11:41:44 +03:00
func DeleteFile ( ctx * context . Context ) {
ctx . Data [ "PageIsDelete" ] = true
2017-10-30 05:04:25 +03:00
ctx . Data [ "BranchLink" ] = ctx . Repo . RepoLink + "/src/" + ctx . Repo . BranchNameSubURL ( )
2016-08-28 11:41:44 +03:00
ctx . Data [ "TreePath" ] = ctx . Repo . TreePath
2017-05-02 03:49:55 +03:00
canCommit := renderCommitRights ( ctx )
2016-08-28 11:41:44 +03:00
ctx . Data [ "commit_summary" ] = ""
ctx . Data [ "commit_message" ] = ""
2017-05-02 03:49:55 +03:00
if canCommit {
ctx . Data [ "commit_choice" ] = frmCommitChoiceDirect
} else {
ctx . Data [ "commit_choice" ] = frmCommitChoiceNewBranch
}
2016-08-28 11:41:44 +03:00
ctx . Data [ "new_branch_name" ] = ""
2017-05-02 03:49:55 +03:00
2016-11-24 10:04:31 +03:00
ctx . HTML ( 200 , tplDeleteFile )
2016-08-11 15:48:08 +03:00
}
2016-08-15 09:38:35 +03:00
2016-11-24 10:04:31 +03:00
// DeleteFilePost response for deleting file
2016-08-15 09:38:35 +03:00
func DeleteFilePost ( ctx * context . Context , form auth . DeleteRepoFileForm ) {
2016-08-28 11:41:44 +03:00
ctx . Data [ "PageIsDelete" ] = true
2017-10-30 05:04:25 +03:00
ctx . Data [ "BranchLink" ] = ctx . Repo . RepoLink + "/src/" + ctx . Repo . BranchNameSubURL ( )
2016-08-28 11:41:44 +03:00
ctx . Data [ "TreePath" ] = ctx . Repo . TreePath
2017-05-02 03:49:55 +03:00
canCommit := renderCommitRights ( ctx )
2016-08-28 11:41:44 +03:00
oldBranchName := ctx . Repo . BranchName
branchName := oldBranchName
2017-05-02 03:49:55 +03:00
if form . CommitChoice == frmCommitChoiceNewBranch {
2016-08-28 11:41:44 +03:00
branchName = form . NewBranchName
}
ctx . Data [ "commit_summary" ] = form . CommitSummary
ctx . Data [ "commit_message" ] = form . CommitMessage
ctx . Data [ "commit_choice" ] = form . CommitChoice
ctx . Data [ "new_branch_name" ] = branchName
2016-08-15 09:38:35 +03:00
if ctx . HasError ( ) {
2016-11-24 10:04:31 +03:00
ctx . HTML ( 200 , tplDeleteFile )
2016-08-15 09:38:35 +03:00
return
}
2016-08-28 11:41:44 +03:00
if oldBranchName != branchName {
if _ , err := ctx . Repo . Repository . GetBranch ( branchName ) ; err == nil {
ctx . Data [ "Err_NewBranchName" ] = true
2016-11-24 10:04:31 +03:00
ctx . RenderWithErr ( ctx . Tr ( "repo.editor.branch_already_exists" , branchName ) , tplDeleteFile , & form )
2016-08-28 11:41:44 +03:00
return
}
2017-05-02 03:49:55 +03:00
} else if ! canCommit {
ctx . Data [ "Err_NewBranchName" ] = true
ctx . Data [ "commit_choice" ] = frmCommitChoiceNewBranch
ctx . RenderWithErr ( ctx . Tr ( "repo.editor.cannot_commit_to_protected_branch" , branchName ) , tplDeleteFile , & form )
return
2016-08-28 11:41:44 +03:00
}
message := strings . TrimSpace ( form . CommitSummary )
if len ( message ) == 0 {
2016-08-30 15:07:50 +03:00
message = ctx . Tr ( "repo.editor.delete" , ctx . Repo . TreePath )
2016-08-28 11:41:44 +03:00
}
form . CommitMessage = strings . TrimSpace ( form . CommitMessage )
if len ( form . CommitMessage ) > 0 {
message += "\n\n" + form . CommitMessage
}
2016-08-17 09:06:38 +03:00
if err := ctx . Repo . Repository . DeleteRepoFile ( ctx . User , models . DeleteRepoFileOptions {
LastCommitID : ctx . Repo . CommitID ,
2016-08-28 11:41:44 +03:00
OldBranch : oldBranchName ,
NewBranch : branchName ,
2016-08-30 15:07:50 +03:00
TreePath : ctx . Repo . TreePath ,
2016-08-28 11:41:44 +03:00
Message : message ,
2016-08-17 09:06:38 +03:00
} ) ; err != nil {
2016-08-15 09:38:35 +03:00
ctx . Handle ( 500 , "DeleteRepoFile" , err )
return
}
2016-08-30 15:07:50 +03:00
ctx . Flash . Success ( ctx . Tr ( "repo.editor.file_delete_success" , ctx . Repo . TreePath ) )
2017-10-30 05:04:25 +03:00
ctx . Redirect ( ctx . Repo . RepoLink + "/src/branch/" + branchName )
2016-08-15 09:38:35 +03:00
}
2016-08-30 15:07:50 +03:00
func renderUploadSettings ( ctx * context . Context ) {
ctx . Data [ "RequireDropzone" ] = true
ctx . Data [ "UploadAllowedTypes" ] = strings . Join ( setting . Repository . Upload . AllowedTypes , "," )
ctx . Data [ "UploadMaxSize" ] = setting . Repository . Upload . FileMaxSize
ctx . Data [ "UploadMaxFiles" ] = setting . Repository . Upload . MaxFiles
}
2016-11-24 10:04:31 +03:00
// UploadFile render upload file page
2016-08-30 15:07:50 +03:00
func UploadFile ( ctx * context . Context ) {
ctx . Data [ "PageIsUpload" ] = true
renderUploadSettings ( ctx )
2017-05-02 03:49:55 +03:00
canCommit := renderCommitRights ( ctx )
2016-08-30 15:07:50 +03:00
2017-06-22 18:30:47 +03:00
treeNames , treePaths := getParentTreeFields ( ctx . Repo . TreePath )
if len ( treeNames ) == 0 {
// We must at least have one element for user to input.
treeNames = [ ] string { "" }
2016-08-30 15:07:50 +03:00
}
ctx . Data [ "TreeNames" ] = treeNames
2017-06-22 18:30:47 +03:00
ctx . Data [ "TreePaths" ] = treePaths
2017-10-30 05:04:25 +03:00
ctx . Data [ "BranchLink" ] = ctx . Repo . RepoLink + "/src/" + ctx . Repo . BranchNameSubURL ( )
2016-08-30 15:07:50 +03:00
ctx . Data [ "commit_summary" ] = ""
ctx . Data [ "commit_message" ] = ""
2017-05-02 03:49:55 +03:00
if canCommit {
ctx . Data [ "commit_choice" ] = frmCommitChoiceDirect
} else {
ctx . Data [ "commit_choice" ] = frmCommitChoiceNewBranch
}
2016-08-30 15:07:50 +03:00
ctx . Data [ "new_branch_name" ] = ""
2016-11-24 10:04:31 +03:00
ctx . HTML ( 200 , tplUploadFile )
2016-08-30 15:07:50 +03:00
}
2016-11-24 10:04:31 +03:00
// UploadFilePost response for uploading file
2016-08-30 15:07:50 +03:00
func UploadFilePost ( ctx * context . Context , form auth . UploadRepoFileForm ) {
ctx . Data [ "PageIsUpload" ] = true
renderUploadSettings ( ctx )
2017-05-02 03:49:55 +03:00
canCommit := renderCommitRights ( ctx )
2016-08-30 15:07:50 +03:00
oldBranchName := ctx . Repo . BranchName
branchName := oldBranchName
2017-05-02 03:49:55 +03:00
if form . CommitChoice == frmCommitChoiceNewBranch {
2016-08-30 15:07:50 +03:00
branchName = form . NewBranchName
}
form . TreePath = strings . Trim ( form . TreePath , " /" )
2017-06-22 18:30:47 +03:00
treeNames , treePaths := getParentTreeFields ( form . TreePath )
if len ( treeNames ) == 0 {
// We must at least have one element for user to input.
treeNames = [ ] string { "" }
2016-08-30 15:07:50 +03:00
}
ctx . Data [ "TreePath" ] = form . TreePath
ctx . Data [ "TreeNames" ] = treeNames
2017-06-22 18:30:47 +03:00
ctx . Data [ "TreePaths" ] = treePaths
2017-10-30 05:04:25 +03:00
ctx . Data [ "BranchLink" ] = ctx . Repo . RepoLink + "/src/branch/" + branchName
2016-08-30 15:07:50 +03:00
ctx . Data [ "commit_summary" ] = form . CommitSummary
ctx . Data [ "commit_message" ] = form . CommitMessage
ctx . Data [ "commit_choice" ] = form . CommitChoice
ctx . Data [ "new_branch_name" ] = branchName
if ctx . HasError ( ) {
2016-11-24 10:04:31 +03:00
ctx . HTML ( 200 , tplUploadFile )
2016-08-30 15:07:50 +03:00
return
}
if oldBranchName != branchName {
if _ , err := ctx . Repo . Repository . GetBranch ( branchName ) ; err == nil {
ctx . Data [ "Err_NewBranchName" ] = true
2016-11-24 10:04:31 +03:00
ctx . RenderWithErr ( ctx . Tr ( "repo.editor.branch_already_exists" , branchName ) , tplUploadFile , & form )
2016-08-30 15:07:50 +03:00
return
}
2017-05-02 03:49:55 +03:00
} else if ! canCommit {
ctx . Data [ "Err_NewBranchName" ] = true
ctx . Data [ "commit_choice" ] = frmCommitChoiceNewBranch
ctx . RenderWithErr ( ctx . Tr ( "repo.editor.cannot_commit_to_protected_branch" , branchName ) , tplUploadFile , & form )
return
2016-08-30 15:07:50 +03:00
}
var newTreePath string
for _ , part := range treeNames {
newTreePath = path . Join ( newTreePath , part )
entry , err := ctx . Repo . Commit . GetTreeEntryByPath ( newTreePath )
if err != nil {
if git . IsErrNotExist ( err ) {
// Means there is no item with that name, so we're good
break
}
ctx . Handle ( 500 , "Repo.Commit.GetTreeEntryByPath" , err )
return
}
// User can only upload files to a directory.
if ! entry . IsDir ( ) {
ctx . Data [ "Err_TreePath" ] = true
2016-11-24 10:04:31 +03:00
ctx . RenderWithErr ( ctx . Tr ( "repo.editor.directory_is_a_file" , part ) , tplUploadFile , & form )
2016-08-30 15:07:50 +03:00
return
}
}
message := strings . TrimSpace ( form . CommitSummary )
if len ( message ) == 0 {
message = ctx . Tr ( "repo.editor.upload_files_to_dir" , form . TreePath )
}
form . CommitMessage = strings . TrimSpace ( form . CommitMessage )
if len ( form . CommitMessage ) > 0 {
message += "\n\n" + form . CommitMessage
}
if err := ctx . Repo . Repository . UploadRepoFiles ( ctx . User , models . UploadRepoFileOptions {
LastCommitID : ctx . Repo . CommitID ,
OldBranch : oldBranchName ,
NewBranch : branchName ,
TreePath : form . TreePath ,
Message : message ,
Files : form . Files ,
} ) ; err != nil {
ctx . Data [ "Err_TreePath" ] = true
2016-11-24 10:04:31 +03:00
ctx . RenderWithErr ( ctx . Tr ( "repo.editor.unable_to_upload_files" , form . TreePath , err ) , tplUploadFile , & form )
2016-08-30 15:07:50 +03:00
return
}
2017-10-30 05:04:25 +03:00
ctx . Redirect ( ctx . Repo . RepoLink + "/src/branch/" + branchName + "/" + form . TreePath )
2016-08-30 15:07:50 +03:00
}
2016-11-24 10:04:31 +03:00
// UploadFileToServer upload file to server file dir not git
2016-08-30 15:07:50 +03:00
func UploadFileToServer ( ctx * context . Context ) {
file , header , err := ctx . Req . FormFile ( "file" )
if err != nil {
ctx . Error ( 500 , fmt . Sprintf ( "FormFile: %v" , err ) )
return
}
defer file . Close ( )
buf := make ( [ ] byte , 1024 )
n , _ := file . Read ( buf )
if n > 0 {
buf = buf [ : n ]
}
fileType := http . DetectContentType ( buf )
if len ( setting . Repository . Upload . AllowedTypes ) > 0 {
allowed := false
for _ , t := range setting . Repository . Upload . AllowedTypes {
t := strings . Trim ( t , " " )
if t == "*/*" || t == fileType {
allowed = true
break
}
}
if ! allowed {
ctx . Error ( 400 , ErrFileTypeForbidden . Error ( ) )
return
}
}
upload , err := models . NewUpload ( header . Filename , buf , file )
if err != nil {
ctx . Error ( 500 , fmt . Sprintf ( "NewUpload: %v" , err ) )
return
}
log . Trace ( "New file uploaded: %s" , upload . UUID )
ctx . JSON ( 200 , map [ string ] string {
"uuid" : upload . UUID ,
} )
}
2016-11-24 10:04:31 +03:00
// RemoveUploadFileFromServer remove file from server file dir
2016-08-30 15:07:50 +03:00
func RemoveUploadFileFromServer ( ctx * context . Context , form auth . RemoveUploadFileForm ) {
if len ( form . File ) == 0 {
ctx . Status ( 204 )
return
}
if err := models . DeleteUploadByUUID ( form . File ) ; err != nil {
ctx . Error ( 500 , fmt . Sprintf ( "DeleteUploadByUUID: %v" , err ) )
return
}
log . Trace ( "Upload file removed: %s" , form . File )
ctx . Status ( 204 )
}