read single file
This commit is contained in:
		
							parent
							
								
									805732fdc7
								
							
						
					
					
						commit
						24678d73f5
					
				|  | @ -81,6 +81,7 @@ var ( | |||
| var ( | ||||
| 	ErrRepoAlreadyExist = errors.New("Repository already exist") | ||||
| 	ErrRepoNotExist     = errors.New("Repository does not exist") | ||||
| 	ErrRepoFileNotExist = errors.New("Target Repo file does not exist") | ||||
| ) | ||||
| 
 | ||||
| func init() { | ||||
|  | @ -463,6 +464,51 @@ func GetBranches(userName, reposName string) ([]string, error) { | |||
| 	return brs, nil | ||||
| } | ||||
| 
 | ||||
| func GetTargetFile(userName, reposName, branchName, commitId, rpath string) (*RepoFile, error) { | ||||
| 	repo, err := git.OpenRepository(RepoPath(userName, reposName)) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	commit, err := repo.GetCommit(branchName, commitId) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	parts := strings.Split(path.Clean(rpath), "/") | ||||
| 
 | ||||
| 	var entry *git.TreeEntry | ||||
| 	tree := commit.Tree | ||||
| 	for i, part := range parts { | ||||
| 		if i == len(parts)-1 { | ||||
| 			entry = tree.EntryByName(part) | ||||
| 			if entry == nil { | ||||
| 				return nil, ErrRepoFileNotExist | ||||
| 			} | ||||
| 		} else { | ||||
| 			tree, err = repo.SubTree(tree, part) | ||||
| 			if err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	size, err := repo.ObjectSize(entry.Id) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	repoFile := &RepoFile{ | ||||
| 		entry, | ||||
| 		rpath, | ||||
| 		size, | ||||
| 		repo, | ||||
| 		commit, | ||||
| 	} | ||||
| 
 | ||||
| 	return repoFile, nil | ||||
| } | ||||
| 
 | ||||
| // GetReposFiles returns a list of file object in given directory of repository.
 | ||||
| func GetReposFiles(userName, reposName, branchName, commitId, rpath string) ([]*RepoFile, error) { | ||||
| 	repo, err := git.OpenRepository(RepoPath(userName, reposName)) | ||||
|  |  | |||
|  | @ -7,6 +7,8 @@ package base | |||
| import ( | ||||
| 	"bytes" | ||||
| 	"path" | ||||
| 	"path/filepath" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/gogits/gfm" | ||||
| ) | ||||
|  | @ -31,6 +33,26 @@ func isLink(link []byte) bool { | |||
| 	return false | ||||
| } | ||||
| 
 | ||||
| func IsMarkdownFile(name string) bool { | ||||
| 	name = strings.ToLower(name) | ||||
| 	switch filepath.Ext(name) { | ||||
| 	case "md", "markdown": | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| func IsReadmeFile(name string) bool { | ||||
| 	name = strings.ToLower(name) | ||||
| 	if len(name) < 6 { | ||||
| 		return false | ||||
| 	} | ||||
| 	if name[:6] == "readme" { | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| type CustomRender struct { | ||||
| 	gfm.Renderer | ||||
| 	urlPrefix string | ||||
|  |  | |||
|  | @ -5,7 +5,6 @@ | |||
| package repo | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/codegangsta/martini" | ||||
|  | @ -47,7 +46,7 @@ func Single(ctx *middleware.Context, params martini.Params) { | |||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	if params["branchname"] == "" { | ||||
| 	if len(params["branchname"]) == 0 { | ||||
| 		params["branchname"] = "master" | ||||
| 	} | ||||
| 
 | ||||
|  | @ -56,7 +55,7 @@ func Single(ctx *middleware.Context, params martini.Params) { | |||
| 
 | ||||
| 	if len(treename) > 0 && treename[len(treename)-1] == '/' { | ||||
| 		ctx.Redirect("/"+ctx.Repo.Owner.LowerName+"/"+ | ||||
| 			ctx.Repo.Repository.Name+"/tree/"+params["branchname"]+"/"+treename[:len(treename)-1], 302) | ||||
| 			ctx.Repo.Repository.Name+"/src/"+params["branchname"]+"/"+treename[:len(treename)-1], 302) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
|  | @ -74,14 +73,78 @@ func Single(ctx *middleware.Context, params martini.Params) { | |||
| 
 | ||||
| 	ctx.Data["Branches"] = brs | ||||
| 
 | ||||
| 	// Directory and file list.
 | ||||
| 	files, err := models.GetReposFiles(params["username"], params["reponame"], | ||||
| 	repoFile, err := models.GetTargetFile(params["username"], params["reponame"], | ||||
| 		params["branchname"], params["commitid"], treename) | ||||
| 	if err != nil { | ||||
| 		log.Error("repo.Single(GetReposFiles): %v", err) | ||||
| 
 | ||||
| 	if err != nil && err != models.ErrRepoFileNotExist { | ||||
| 		log.Error("repo.Single(GetTargetFile): %v", err) | ||||
| 		ctx.Error(404) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	branchLink := "/" + ctx.Repo.Owner.LowerName + "/" + ctx.Repo.Repository.Name + "/src/" + params["branchname"] | ||||
| 
 | ||||
| 	if repoFile != nil && repoFile.IsFile() { | ||||
| 		if repoFile.Size > 1024*1024 || repoFile.Filemode != git.FileModeBlob { | ||||
| 			ctx.Data["FileIsLarge"] = true | ||||
| 		} else if blob, err := repoFile.LookupBlob(); err != nil { | ||||
| 			log.Error("repo.Single(repoFile.LookupBlob): %v", err) | ||||
| 			ctx.Error(404) | ||||
| 		} else { | ||||
| 			ctx.Data["IsFile"] = true | ||||
| 			ctx.Data["FileName"] = repoFile.Name | ||||
| 
 | ||||
| 			readmeExist := base.IsMarkdownFile(repoFile.Name) || base.IsReadmeFile(repoFile.Name) | ||||
| 			ctx.Data["ReadmeExist"] = readmeExist | ||||
| 			if readmeExist { | ||||
| 				ctx.Data["FileContent"] = string(base.RenderMarkdown(blob.Contents(), "")) | ||||
| 			} else { | ||||
| 				ctx.Data["FileContent"] = string(blob.Contents()) | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 	} else { | ||||
| 		// Directory and file list.
 | ||||
| 		files, err := models.GetReposFiles(params["username"], params["reponame"], | ||||
| 			params["branchname"], params["commitid"], treename) | ||||
| 		if err != nil { | ||||
| 			log.Error("repo.Single(GetReposFiles): %v", err) | ||||
| 			ctx.Error(404) | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		ctx.Data["Files"] = files | ||||
| 
 | ||||
| 		var readmeFile *models.RepoFile | ||||
| 
 | ||||
| 		for _, f := range files { | ||||
| 			if !f.IsFile() || !base.IsReadmeFile(f.Name) { | ||||
| 				continue | ||||
| 			} else { | ||||
| 				readmeFile = f | ||||
| 				break | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		if readmeFile != nil { | ||||
| 			ctx.Data["ReadmeExist"] = true | ||||
| 			// if file large than 1M not show it
 | ||||
| 			if readmeFile.Size > 1024*1024 || readmeFile.Filemode != git.FileModeBlob { | ||||
| 				ctx.Data["FileIsLarge"] = true | ||||
| 			} else if blob, err := readmeFile.LookupBlob(); err != nil { | ||||
| 				log.Error("repo.Single(readmeFile.LookupBlob): %v", err) | ||||
| 				ctx.Error(404) | ||||
| 				return | ||||
| 			} else { | ||||
| 				// current repo branch link
 | ||||
| 				urlPrefix := "http://" + base.Domain + branchLink | ||||
| 
 | ||||
| 				ctx.Data["FileName"] = readmeFile.Name | ||||
| 				ctx.Data["FileContent"] = string(base.RenderMarkdown(blob.Contents(), urlPrefix)) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	ctx.Data["Username"] = params["username"] | ||||
| 	ctx.Data["Reponame"] = params["reponame"] | ||||
| 	ctx.Data["Branchname"] = params["branchname"] | ||||
|  | @ -111,39 +174,10 @@ func Single(ctx *middleware.Context, params martini.Params) { | |||
| 	} | ||||
| 	ctx.Data["LastCommit"] = commit | ||||
| 
 | ||||
| 	var readmeFile *models.RepoFile | ||||
| 
 | ||||
| 	for _, f := range files { | ||||
| 		if !f.IsFile() || len(f.Name) < 6 { | ||||
| 			continue | ||||
| 		} else if strings.ToLower(f.Name[:6]) == "readme" { | ||||
| 			readmeFile = f | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if readmeFile != nil { | ||||
| 		ctx.Data["ReadmeExist"] = true | ||||
| 		// if file large than 1M not show it
 | ||||
| 		if readmeFile.Size > 1024*1024 || readmeFile.Filemode != git.FileModeBlob { | ||||
| 			ctx.Data["FileIsLarge"] = true | ||||
| 		} else if blob, err := readmeFile.LookupBlob(); err != nil { | ||||
| 			ctx.Data["ReadmeExist"] = false | ||||
| 		} else { | ||||
| 			// current repo branch link
 | ||||
| 			urlPrefix := "http://" + base.Domain + "/" + ctx.Repo.Owner.LowerName + "/" + | ||||
| 				ctx.Repo.Repository.Name + "/tree/" + params["branchname"] | ||||
| 
 | ||||
| 			ctx.Data["ReadmeContent"] = string(base.RenderMarkdown(blob.Contents(), urlPrefix)) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	fmt.Println(Paths) | ||||
| 
 | ||||
| 	ctx.Data["Paths"] = Paths | ||||
| 	ctx.Data["Treenames"] = treenames | ||||
| 	ctx.Data["IsRepoToolbarSource"] = true | ||||
| 	ctx.Data["Files"] = files | ||||
| 	ctx.Data["BranchLink"] = branchLink | ||||
| 	ctx.HTML(200, "repo/single", ctx.Data) | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -8,104 +8,35 @@ | |||
|         Need to fill in some guide. | ||||
|         {{else}} | ||||
|         <div class="source-toolbar"> | ||||
|             {{ $username := .Username}} | ||||
|             {{ $reponame := .Reponame}} | ||||
|             {{ $branchname := .Branchname}} | ||||
|             {{ $treenames := .Treenames}} | ||||
|             {{ $repoLink := .RepositoryLink}} | ||||
|             {{ $n := len $treenames}} | ||||
|             <button class="btn btn-default pull-right"><i class="fa fa-plus-square"></i>Add File</button> | ||||
|             {{ $n := len .Treenames}} | ||||
|             {{if not .IsFile}}<button class="btn btn-default pull-right"><i class="fa fa-plus-square"></i>Add File</button>{{end}} | ||||
|             <div class="dropdown branch-switch"> | ||||
|                 <a href="#" class="btn btn-success dropdown-toggle" data-toggle="dropdown"><i class="fa fa-chain"></i>{{$branchname}}   | ||||
|                 <a href="#" class="btn btn-success dropdown-toggle" data-toggle="dropdown"><i class="fa fa-chain"></i>{{.Branchname}}   | ||||
|                     <b class="caret"></b></a> | ||||
|                 <ul class="dropdown-menu"> | ||||
|                     {{range .Branches}} | ||||
|                     <li><a {{if eq . $branchname}}class="current" {{end}}href="/{{$repoLink}}/tree/{{.}}">{{.}}</a></li> | ||||
|                     <li><a {{if eq . $.Branchname}}class="current" {{end}}href="{{$.BranchLink}}">{{.}}</a></li> | ||||
|                     {{end}} | ||||
|                 </ul> | ||||
|             </div> | ||||
|             {{$paths := .Paths}} | ||||
|             {{ $l := Subtract $n 1}} | ||||
|             <ol class="breadcrumb"> | ||||
|                 <li class="root dir"> | ||||
|                     <a href="/{{$username}}/{{$reponame}}/tree/{{$branchname}}">{{.Repository.Name}}</a></li> | ||||
|                 {{range $i, $v := $treenames}} | ||||
|                     <a href="{{.BranchLink}}">{{.Repository.Name}}</a></li> | ||||
|                 {{range $i, $v := .Treenames}} | ||||
|                 <li class="dir"> | ||||
|                     {{if eq $i $l}}{{$v}} | ||||
|                     {{else}} | ||||
|                     <a href="/{{$username}}/{{$reponame}}/tree/{{$branchname}}/{{index $paths $i}}">{{$v}}</a>  | ||||
|                     <a href="{{$.BranchLink}}/{{index $.Paths $i}}">{{$v}}</a>  | ||||
|                     {{end}} | ||||
|                 </li> | ||||
|                 {{end}} | ||||
|             </ol> | ||||
|         </div> | ||||
| 
 | ||||
|         <div class="panel panel-default info-box"> | ||||
|             <div class="panel-heading info-head"> | ||||
|                 <a href="/{{$username}}/{{$reponame}}/commit/{{.LastCommit.Oid.String}}">{{.LastCommit.Message}}</a> | ||||
|             </div> | ||||
|             <div class="panel-body info-content"> | ||||
|                 <a href="/user/{{.LastCommit.Author.Name}}">{{.LastCommit.Author.Name}}</a> <span class="text-muted">{{TimeSince .LastCommit.Author.When}}</span> | ||||
|             </div> | ||||
|             <table class="panel-footer table file-list"> | ||||
|                 <thead class="hidden"> | ||||
|                 <tr> | ||||
|                     <th class="icon"></th> | ||||
|                     <th class="name">Filename</th> | ||||
|                     <th class="text">Message</th> | ||||
|                     <th class="date">Date modified</th> | ||||
|                 </tr> | ||||
|                 </thead> | ||||
|                 <tbody> | ||||
|                 {{if .HasParentPath}} | ||||
|                     <tr class="has-parent"> | ||||
|                         <td class="icon"><a href="/{{$username}}/{{$reponame}}/tree/{{$branchname}}{{.ParentPath}}"><i class="fa fa-reply"></i></a></td> | ||||
|                         <td class="name"><a href="/{{$username}}/{{$reponame}}/tree/{{$branchname}}{{.ParentPath}}">..</a></td> | ||||
|                         <td class="text"></td> | ||||
|                         <td class="date"></td> | ||||
|                     </tr> | ||||
|                 {{end}} | ||||
|                 {{range .Files}} | ||||
|                 <tr | ||||
|                 {{if .IsDir}}class="is-dir"{{end}}> | ||||
|                 <td class="icon"> | ||||
|                     <i class="fa {{if .IsDir}}fa-folder{{else}}fa-file-text-o{{end}}"></i> | ||||
|                 </td> | ||||
|                 <td class="name"> | ||||
|                     <span class="wrap"> | ||||
|                         {{if .IsDir}} | ||||
|                         <a href="/{{$username}}/{{$reponame}}/tree/{{$branchname}}/{{.Path}}">{{.Name}}</a> | ||||
|                         {{else}} | ||||
|                         <a href="/{{$username}}/{{$reponame}}/blob/{{$branchname}}/{{.Name}}">{{.Name}}</a> | ||||
|                         {{end}} | ||||
|                     </span> | ||||
|                 </td> | ||||
|                 <td class="text"> | ||||
|                     <span class="wrap"><a href="/{{$username}}/{{$reponame}}/commit/{{.Commit.Oid}}">{{.Commit.Message}}</a></span> | ||||
|                 </td> | ||||
|                 <td class="date"> | ||||
|                     <span class="wrap">{{TimeSince .Commit.Committer.When}}</span> | ||||
|                 </td> | ||||
|                 </tr> | ||||
|                 {{end}} | ||||
|                 </tbody> | ||||
|             </table> | ||||
|         </div> | ||||
|         {{if .ReadmeExist}} | ||||
|         <div class="panel panel-default file-content"> | ||||
|             <div class="panel-heading file-head"> | ||||
|                 <i class="icon fa fa-book"></i> README.md | ||||
|             </div> | ||||
|             {{if .FileIsLarge}} | ||||
|                 <div class="panel-footer"> | ||||
|                     Large file size 1000kb | ||||
|                 </div> | ||||
|             {{else}} | ||||
|                 <div class="panel-body file-body markdown"> | ||||
|                     {{.ReadmeContent|str2html}} | ||||
|                 </div> | ||||
|             {{end}} | ||||
|         </div> | ||||
|         {{if .IsFile}} | ||||
|             {{template "repo/single_file" .}} | ||||
|         {{else}} | ||||
|             {{template "repo/single_list" .}} | ||||
|         {{end}} | ||||
|         {{end}} | ||||
|     </div> | ||||
|  |  | |||
|  | @ -0,0 +1,20 @@ | |||
| <div class="panel panel-default file-content"> | ||||
|     <div class="panel-heading file-head"> | ||||
|         <i class="icon fa fa-book"></i> {{.FileName}} | ||||
|     </div> | ||||
|     {{if .FileIsLarge}} | ||||
|         <div class="panel-footer"> | ||||
|             Large file size 1000kb | ||||
|         </div> | ||||
|     {{else}} | ||||
|         {{if .ReadmeExist}} | ||||
|             <div class="panel-body file-body markdown"> | ||||
|                 {{.FileContent|str2html}} | ||||
|             </div> | ||||
|         {{else}} | ||||
|             <div class="panel-body file-body markdown"> | ||||
|                 <pre><code>{{.FileContent|str2html}}</code></pre> | ||||
|             </div> | ||||
|         {{end}} | ||||
|     {{end}} | ||||
| </div> | ||||
|  | @ -0,0 +1,54 @@ | |||
| <div class="panel panel-default info-box"> | ||||
|     <div class="panel-heading info-head"> | ||||
|         <a href="/{{.Username}}/{{.Reponame}}/commit/{{.LastCommit.Oid.String}}">{{.LastCommit.Message}}</a> | ||||
|     </div> | ||||
|     <div class="panel-body info-content"> | ||||
|         <a href="/user/{{.LastCommit.Author.Name}}">{{.LastCommit.Author.Name}}</a> <span class="text-muted">{{TimeSince .LastCommit.Author.When}}</span> | ||||
|     </div> | ||||
|     <table class="panel-footer table file-list"> | ||||
|         <thead class="hidden"> | ||||
|         <tr> | ||||
|             <th class="icon"></th> | ||||
|             <th class="name">Filename</th> | ||||
|             <th class="text">Message</th> | ||||
|             <th class="date">Date modified</th> | ||||
|         </tr> | ||||
|         </thead> | ||||
|         <tbody> | ||||
|         {{if .HasParentPath}} | ||||
|             <tr class="has-parent"> | ||||
|                 <td class="icon"><a href="{{.BranchLink}}{{.ParentPath}}"><i class="fa fa-reply"></i></a></td> | ||||
|                 <td class="name"><a href="{{.BranchLink}}{{.ParentPath}}">..</a></td> | ||||
|                 <td class="text"></td> | ||||
|                 <td class="date"></td> | ||||
|             </tr> | ||||
|         {{end}} | ||||
|         {{range .Files}} | ||||
|         <tr | ||||
|         {{if .IsDir}}class="is-dir"{{end}}> | ||||
|         <td class="icon"> | ||||
|             <i class="fa {{if .IsDir}}fa-folder{{else}}fa-file-text-o{{end}}"></i> | ||||
|         </td> | ||||
|         <td class="name"> | ||||
|             <span class="wrap"> | ||||
|                 {{if .IsDir}} | ||||
|                 <a href="{{$.BranchLink}}/{{.Path}}">{{.Name}}</a> | ||||
|                 {{else}} | ||||
|                 <a href="{{$.BranchLink}}/{{.Path}}">{{.Name}}</a> | ||||
|                 {{end}} | ||||
|             </span> | ||||
|         </td> | ||||
|         <td class="text"> | ||||
|             <span class="wrap"><a href="/{{$.Username}}/{{$.Reponame}}/commit/{{.Commit.Oid}}">{{.Commit.Message}}</a></span> | ||||
|         </td> | ||||
|         <td class="date"> | ||||
|             <span class="wrap">{{TimeSince .Commit.Committer.When}}</span> | ||||
|         </td> | ||||
|         </tr> | ||||
|         {{end}} | ||||
|         </tbody> | ||||
|     </table> | ||||
| </div> | ||||
| {{if .ReadmeExist}} | ||||
|     {{template "repo/single_file" .}} | ||||
| {{end}} | ||||
							
								
								
									
										4
									
								
								web.go
								
								
								
								
							
							
						
						
									
										4
									
								
								web.go
								
								
								
								
							|  | @ -107,9 +107,9 @@ func runWeb(*cli.Context) { | |||
| 	m.Get("/:username/:reponame/pulls", ignSignIn, middleware.RepoAssignment(true), repo.Pulls) | ||||
| 	m.Get("/:username/:reponame/branches", ignSignIn, middleware.RepoAssignment(true), repo.Branches) | ||||
| 	m.Get("/:username/:reponame/action/:action", reqSignIn, middleware.RepoAssignment(true), repo.Action) | ||||
| 	m.Get("/:username/:reponame/tree/:branchname/**", | ||||
| 	m.Get("/:username/:reponame/src/:branchname/**", | ||||
| 		ignSignIn, middleware.RepoAssignment(true), repo.Single) | ||||
| 	m.Get("/:username/:reponame/tree/:branchname", | ||||
| 	m.Get("/:username/:reponame/src/:branchname", | ||||
| 		ignSignIn, middleware.RepoAssignment(true), repo.Single) | ||||
| 	m.Get("/:username/:reponame/commit/:commitid/**", ignSignIn, middleware.RepoAssignment(true), repo.Single) | ||||
| 	m.Get("/:username/:reponame/commit/:commitid", ignSignIn, middleware.RepoAssignment(true), repo.Single) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue