Browse Source

Working on issues

Unknown 11 years ago
parent
commit
61e2922601
7 changed files with 443 additions and 310 deletions
  1. 1 1
      gogs.go
  2. 0 1
      models/action.go
  3. 117 6
      models/issue.go
  4. 1 1
      models/models.go
  5. 30 0
      routers/repo/issue.go
  6. 294 0
      routers/repo/repo.go
  7. 0 301
      routers/repo/single.go

+ 1 - 1
gogs.go

@@ -20,7 +20,7 @@ import (
 // Test that go1.2 tag above is included in builds. main.go refers to this definition.
 // Test that go1.2 tag above is included in builds. main.go refers to this definition.
 const go12tag = true
 const go12tag = true
 
 
-const APP_VER = "0.1.5.0322.2"
+const APP_VER = "0.1.6.0323.1"
 
 
 func init() {
 func init() {
 	base.AppVer = APP_VER
 	base.AppVer = APP_VER

+ 0 - 1
models/action.go

@@ -88,7 +88,6 @@ func CommitRepoAction(userId int64, userName string,
 		return err
 		return err
 	}
 	}
 	repo.IsBare = false
 	repo.IsBare = false
-	repo.Updated = time.Now()
 	if err = UpdateRepository(repo); err != nil {
 	if err = UpdateRepository(repo); err != nil {
 		return err
 		return err
 	}
 	}

+ 117 - 6
models/issue.go

@@ -4,16 +4,127 @@
 
 
 package models
 package models
 
 
+import (
+	"strings"
+	"time"
+
+	"github.com/gogits/gogs/modules/base"
+)
+
+// Issue represents an issue or pull request of repository.
 type Issue struct {
 type Issue struct {
-	Id       int64
-	RepoId   int64 `xorm:"index"`
-	PosterId int64
+	Id          int64
+	Index       int64 // Index in one repository.
+	Name        string
+	RepoId      int64 `xorm:"index"`
+	PosterId    int64
+	MilestoneId int64
+	AssigneeId  int64
+	IsPull      bool // Indicates whether is a pull request or not.
+	IsClosed    bool
+	Labels      string
+	Mentions    string
+	Content     string
+	NumComments int
+	Created     time.Time `xorm:"created"`
+	Updated     time.Time `xorm:"updated"`
+}
+
+// CreateIssue creates new issue for repository.
+func CreateIssue(userId, repoId, milestoneId, assigneeId int64, name, labels, mentions, content string, isPull bool) error {
+	count, err := GetIssueCount(repoId)
+	if err != nil {
+		return err
+	}
+
+	_, err = orm.Insert(&Issue{
+		Index:       count + 1,
+		Name:        name,
+		RepoId:      repoId,
+		PosterId:    userId,
+		MilestoneId: milestoneId,
+		AssigneeId:  assigneeId,
+		IsPull:      isPull,
+		Labels:      labels,
+		Mentions:    mentions,
+		Content:     content,
+	})
+	return err
 }
 }
 
 
-type PullRequest struct {
-	Id int64
+// GetIssueCount returns count of issues in the repository.
+func GetIssueCount(repoId int64) (int64, error) {
+	return orm.Count(&Issue{RepoId: repoId})
 }
 }
 
 
+// GetIssues returns a list of issues by given conditions.
+func GetIssues(userId, repoId, posterId, milestoneId int64, page int, isClosed, isMention bool, labels, sortType string) ([]Issue, error) {
+	sess := orm.Limit(20, (page-1)*20).Where("repo_id=?", repoId).And("is_closed=?", isClosed)
+	if userId > 0 {
+		sess = sess.And("assignee_id=?", userId)
+	} else if posterId > 0 {
+		sess = sess.And("poster_id=?", posterId)
+	} else if isMention {
+		sess = sess.And("mentions like '%$" + base.ToStr(userId) + "|%'")
+	}
+
+	if milestoneId > 0 {
+		sess = sess.And("milestone_id=?", milestoneId)
+	}
+
+	if len(labels) > 0 {
+		for _, label := range strings.Split(labels, ",") {
+			sess = sess.And("mentions like '%$" + label + "|%'")
+		}
+	}
+
+	switch sortType {
+	case "oldest":
+		sess = sess.Asc("created")
+	case "recentupdate":
+		sess = sess.Desc("updated")
+	case "leastupdate":
+		sess = sess.Asc("updated")
+	case "mostcomment":
+		sess = sess.Desc("num_comments")
+	case "leastcomment":
+		sess = sess.Asc("num_comments")
+	default:
+		sess = sess.Desc("created")
+	}
+
+	var issues []Issue
+	err := sess.Find(&issues)
+	return issues, err
+}
+
+// Label represents a list of labels of repository for issues.
+type Label struct {
+	Id     int64
+	RepoId int64 `xorm:"index"`
+	Names  string
+	Colors string
+}
+
+// Milestone represents a milestone of repository.
+type Milestone struct {
+	Id        int64
+	Name      string
+	RepoId    int64 `xorm:"index"`
+	IsClosed  bool
+	Content   string
+	NumIssues int
+	DueDate   time.Time
+	Created   time.Time `xorm:"created"`
+}
+
+// Comment represents a comment in commit and issue page.
 type Comment struct {
 type Comment struct {
-	Id int64
+	Id       int64
+	PosterId int64
+	IssueId  int64
+	CommitId int64
+	Line     int
+	Content  string
+	Created  time.Time `xorm:"created"`
 }
 }

+ 1 - 1
models/models.go

@@ -72,7 +72,7 @@ func setEngine() {
 func NewEngine() {
 func NewEngine() {
 	setEngine()
 	setEngine()
 	if err := orm.Sync(new(User), new(PublicKey), new(Repository), new(Watch),
 	if err := orm.Sync(new(User), new(PublicKey), new(Repository), new(Watch),
-		new(Action), new(Access)); err != nil {
+		new(Action), new(Access), new(Issue)); err != nil {
 		fmt.Printf("sync database struct error: %v\n", err)
 		fmt.Printf("sync database struct error: %v\n", err)
 		os.Exit(2)
 		os.Exit(2)
 	}
 	}

+ 30 - 0
routers/repo/issue.go

@@ -0,0 +1,30 @@
+// 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 (
+	"github.com/codegangsta/martini"
+
+	"github.com/gogits/gogs/models"
+	"github.com/gogits/gogs/modules/base"
+	"github.com/gogits/gogs/modules/middleware"
+)
+
+func Issues(ctx *middleware.Context, params martini.Params) {
+	ctx.Data["IsRepoToolbarIssues"] = true
+
+	milestoneId, _ := base.StrTo(params["milestone"]).Int()
+	page, _ := base.StrTo(params["page"]).Int()
+
+	var err error
+	ctx.Data["Issues"], err = models.GetIssues(0, ctx.Repo.Repository.Id, 0,
+		int64(milestoneId), page, params["state"] == "closed", false, params["labels"], params["sortType"])
+	if err != nil {
+		ctx.Handle(200, "issue.Issues: %v", err)
+		return
+	}
+
+	ctx.HTML(200, "repo/issues")
+}

+ 294 - 0
routers/repo/repo.go

@@ -5,8 +5,17 @@
 package repo
 package repo
 
 
 import (
 import (
+	"path"
+	"strings"
+
+	"github.com/codegangsta/martini"
+
+	"github.com/gogits/git"
+	"github.com/gogits/webdav"
+
 	"github.com/gogits/gogs/models"
 	"github.com/gogits/gogs/models"
 	"github.com/gogits/gogs/modules/auth"
 	"github.com/gogits/gogs/modules/auth"
+	"github.com/gogits/gogs/modules/base"
 	"github.com/gogits/gogs/modules/log"
 	"github.com/gogits/gogs/modules/log"
 	"github.com/gogits/gogs/modules/middleware"
 	"github.com/gogits/gogs/modules/middleware"
 )
 )
@@ -61,3 +70,288 @@ func SettingPost(ctx *middleware.Context) {
 	log.Trace("%s Repository deleted: %s/%s", ctx.Req.RequestURI, ctx.User.LowerName, ctx.Repo.Repository.LowerName)
 	log.Trace("%s Repository deleted: %s/%s", ctx.Req.RequestURI, ctx.User.LowerName, ctx.Repo.Repository.LowerName)
 	ctx.Redirect("/", 302)
 	ctx.Redirect("/", 302)
 }
 }
+
+func Branches(ctx *middleware.Context, params martini.Params) {
+	if !ctx.Repo.IsValid {
+		return
+	}
+
+	brs, err := models.GetBranches(params["username"], params["reponame"])
+	if err != nil {
+		ctx.Handle(200, "repo.Branches", err)
+		return
+	} else if len(brs) == 0 {
+		ctx.Error(404)
+		return
+	}
+
+	ctx.Data["Username"] = params["username"]
+	ctx.Data["Reponame"] = params["reponame"]
+
+	ctx.Data["Branchname"] = brs[0]
+	ctx.Data["Branches"] = brs
+	ctx.Data["IsRepoToolbarBranches"] = true
+
+	ctx.HTML(200, "repo/branches")
+}
+
+func Single(ctx *middleware.Context, params martini.Params) {
+	if !ctx.Repo.IsValid {
+		return
+	}
+
+	if len(params["branchname"]) == 0 {
+		params["branchname"] = "master"
+	}
+
+	// Get tree path
+	treename := params["_1"]
+
+	if len(treename) > 0 && treename[len(treename)-1] == '/' {
+		ctx.Redirect("/"+ctx.Repo.Owner.LowerName+"/"+
+			ctx.Repo.Repository.Name+"/src/"+params["branchname"]+"/"+treename[:len(treename)-1], 302)
+		return
+	}
+
+	ctx.Data["IsRepoToolbarSource"] = true
+
+	// Branches.
+	brs, err := models.GetBranches(params["username"], params["reponame"])
+	if err != nil {
+		log.Error("repo.Single(GetBranches): %v", err)
+		ctx.Error(404)
+		return
+	} else if ctx.Repo.Repository.IsBare {
+		ctx.Data["IsBareRepo"] = true
+		ctx.HTML(200, "repo/single")
+		return
+	}
+
+	ctx.Data["Branches"] = brs
+
+	repoFile, err := models.GetTargetFile(params["username"], params["reponame"],
+		params["branchname"], params["commitid"], treename)
+
+	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 len(treename) != 0 && repoFile == nil {
+		ctx.Error(404)
+		return
+	}
+
+	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
+			ext := path.Ext(repoFile.Name)
+			if len(ext) > 0 {
+				ext = ext[1:]
+			}
+			ctx.Data["FileExt"] = ext
+
+			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
+
+				ctx.Data["FileName"] = readmeFile.Name
+				ctx.Data["FileContent"] = string(base.RenderMarkdown(blob.Contents(), branchLink))
+			}
+		}
+	}
+
+	ctx.Data["Username"] = params["username"]
+	ctx.Data["Reponame"] = params["reponame"]
+	ctx.Data["Branchname"] = params["branchname"]
+
+	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]
+		}
+	}
+
+	// Get latest commit according username and repo name
+	commit, err := models.GetCommit(params["username"], params["reponame"],
+		params["branchname"], params["commitid"])
+	if err != nil {
+		log.Error("repo.Single(GetCommit): %v", err)
+		ctx.Error(404)
+		return
+	}
+	ctx.Data["LastCommit"] = commit
+
+	ctx.Data["Paths"] = Paths
+	ctx.Data["Treenames"] = treenames
+	ctx.Data["BranchLink"] = branchLink
+	ctx.HTML(200, "repo/single")
+}
+
+func Http(ctx *middleware.Context, params martini.Params) {
+	/*if !ctx.Repo.IsValid {
+		return
+	}*/
+
+	// TODO: access check
+
+	username := params["username"]
+	reponame := params["reponame"]
+	if strings.HasSuffix(reponame, ".git") {
+		reponame = reponame[:len(reponame)-4]
+	}
+
+	prefix := path.Join("/", username, params["reponame"])
+	server := &webdav.Server{
+		Fs:         webdav.Dir(models.RepoPath(username, reponame)),
+		TrimPrefix: prefix,
+		Listings:   true,
+	}
+
+	server.ServeHTTP(ctx.ResponseWriter, ctx.Req)
+}
+
+func Setting(ctx *middleware.Context, params martini.Params) {
+	if !ctx.Repo.IsOwner {
+		ctx.Error(404)
+		return
+	}
+
+	ctx.Data["IsRepoToolbarSetting"] = true
+
+	if ctx.Repo.Repository.IsBare {
+		ctx.Data["IsBareRepo"] = true
+		ctx.HTML(200, "repo/setting")
+		return
+	}
+
+	var title string
+	if t, ok := ctx.Data["Title"].(string); ok {
+		title = t
+	}
+
+	if len(params["branchname"]) == 0 {
+		params["branchname"] = "master"
+	}
+
+	ctx.Data["Branchname"] = params["branchname"]
+	ctx.Data["Title"] = title + " - settings"
+	ctx.HTML(200, "repo/setting")
+}
+
+func Commits(ctx *middleware.Context, params martini.Params) {
+	brs, err := models.GetBranches(params["username"], params["reponame"])
+	if err != nil {
+		ctx.Handle(200, "repo.Commits", err)
+		return
+	} else if len(brs) == 0 {
+		ctx.Error(404)
+		return
+	}
+
+	ctx.Data["IsRepoToolbarCommits"] = true
+	commits, err := models.GetCommits(params["username"],
+		params["reponame"], params["branchname"])
+	if err != nil {
+		ctx.Error(404)
+		return
+	}
+	ctx.Data["Username"] = params["username"]
+	ctx.Data["Reponame"] = params["reponame"]
+	ctx.Data["CommitCount"] = commits.Len()
+	ctx.Data["Commits"] = commits
+	ctx.HTML(200, "repo/commits")
+}
+
+func Pulls(ctx *middleware.Context) {
+	ctx.Data["IsRepoToolbarPulls"] = true
+	ctx.HTML(200, "repo/pulls")
+}
+
+func Action(ctx *middleware.Context, params martini.Params) {
+	var err error
+	switch params["action"] {
+	case "watch":
+		err = models.WatchRepo(ctx.User.Id, ctx.Repo.Repository.Id, true)
+	case "unwatch":
+		err = models.WatchRepo(ctx.User.Id, ctx.Repo.Repository.Id, false)
+	case "desc":
+		if !ctx.Repo.IsOwner {
+			ctx.Error(404)
+			return
+		}
+
+		ctx.Repo.Repository.Description = ctx.Query("desc")
+		ctx.Repo.Repository.Website = ctx.Query("site")
+		err = models.UpdateRepository(ctx.Repo.Repository)
+	}
+
+	if err != nil {
+		log.Error("repo.Action(%s): %v", params["action"], err)
+		ctx.JSON(200, map[string]interface{}{
+			"ok":  false,
+			"err": err.Error(),
+		})
+		return
+	}
+	ctx.JSON(200, map[string]interface{}{
+		"ok": true,
+	})
+}

+ 0 - 301
routers/repo/single.go

@@ -1,301 +0,0 @@
-// 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 (
-	"path"
-	"strings"
-
-	"github.com/codegangsta/martini"
-
-	"github.com/gogits/git"
-	"github.com/gogits/webdav"
-
-	"github.com/gogits/gogs/models"
-	"github.com/gogits/gogs/modules/base"
-	"github.com/gogits/gogs/modules/log"
-	"github.com/gogits/gogs/modules/middleware"
-)
-
-func Branches(ctx *middleware.Context, params martini.Params) {
-	if !ctx.Repo.IsValid {
-		return
-	}
-
-	brs, err := models.GetBranches(params["username"], params["reponame"])
-	if err != nil {
-		ctx.Handle(200, "repo.Branches", err)
-		return
-	} else if len(brs) == 0 {
-		ctx.Error(404)
-		return
-	}
-
-	ctx.Data["Username"] = params["username"]
-	ctx.Data["Reponame"] = params["reponame"]
-
-	ctx.Data["Branchname"] = brs[0]
-	ctx.Data["Branches"] = brs
-	ctx.Data["IsRepoToolbarBranches"] = true
-
-	ctx.HTML(200, "repo/branches")
-}
-
-func Single(ctx *middleware.Context, params martini.Params) {
-	if !ctx.Repo.IsValid {
-		return
-	}
-
-	if len(params["branchname"]) == 0 {
-		params["branchname"] = "master"
-	}
-
-	// Get tree path
-	treename := params["_1"]
-
-	if len(treename) > 0 && treename[len(treename)-1] == '/' {
-		ctx.Redirect("/"+ctx.Repo.Owner.LowerName+"/"+
-			ctx.Repo.Repository.Name+"/src/"+params["branchname"]+"/"+treename[:len(treename)-1], 302)
-		return
-	}
-
-	ctx.Data["IsRepoToolbarSource"] = true
-
-	// Branches.
-	brs, err := models.GetBranches(params["username"], params["reponame"])
-	if err != nil {
-		log.Error("repo.Single(GetBranches): %v", err)
-		ctx.Error(404)
-		return
-	} else if ctx.Repo.Repository.IsBare {
-		ctx.Data["IsBareRepo"] = true
-		ctx.HTML(200, "repo/single")
-		return
-	}
-
-	ctx.Data["Branches"] = brs
-
-	repoFile, err := models.GetTargetFile(params["username"], params["reponame"],
-		params["branchname"], params["commitid"], treename)
-
-	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 len(treename) != 0 && repoFile == nil {
-		ctx.Error(404)
-		return
-	}
-
-	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
-			ext := path.Ext(repoFile.Name)
-			if len(ext) > 0 {
-				ext = ext[1:]
-			}
-			ctx.Data["FileExt"] = ext
-
-			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
-
-				ctx.Data["FileName"] = readmeFile.Name
-				ctx.Data["FileContent"] = string(base.RenderMarkdown(blob.Contents(), branchLink))
-			}
-		}
-	}
-
-	ctx.Data["Username"] = params["username"]
-	ctx.Data["Reponame"] = params["reponame"]
-	ctx.Data["Branchname"] = params["branchname"]
-
-	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]
-		}
-	}
-
-	// Get latest commit according username and repo name
-	commit, err := models.GetCommit(params["username"], params["reponame"],
-		params["branchname"], params["commitid"])
-	if err != nil {
-		log.Error("repo.Single(GetCommit): %v", err)
-		ctx.Error(404)
-		return
-	}
-	ctx.Data["LastCommit"] = commit
-
-	ctx.Data["Paths"] = Paths
-	ctx.Data["Treenames"] = treenames
-	ctx.Data["BranchLink"] = branchLink
-	ctx.HTML(200, "repo/single")
-}
-
-func Http(ctx *middleware.Context, params martini.Params) {
-	/*if !ctx.Repo.IsValid {
-		return
-	}*/
-
-	// TODO: access check
-
-	username := params["username"]
-	reponame := params["reponame"]
-	if strings.HasSuffix(reponame, ".git") {
-		reponame = reponame[:len(reponame)-4]
-	}
-
-	prefix := path.Join("/", username, params["reponame"])
-	server := &webdav.Server{
-		Fs:         webdav.Dir(models.RepoPath(username, reponame)),
-		TrimPrefix: prefix,
-		Listings:   true,
-	}
-
-	server.ServeHTTP(ctx.ResponseWriter, ctx.Req)
-}
-
-func Setting(ctx *middleware.Context, params martini.Params) {
-	if !ctx.Repo.IsOwner {
-		ctx.Error(404)
-		return
-	}
-
-	ctx.Data["IsRepoToolbarSetting"] = true
-
-	if ctx.Repo.Repository.IsBare {
-		ctx.Data["IsBareRepo"] = true
-		ctx.HTML(200, "repo/setting")
-		return
-	}
-
-	var title string
-	if t, ok := ctx.Data["Title"].(string); ok {
-		title = t
-	}
-
-	if len(params["branchname"]) == 0 {
-		params["branchname"] = "master"
-	}
-
-	ctx.Data["Branchname"] = params["branchname"]
-	ctx.Data["Title"] = title + " - settings"
-	ctx.HTML(200, "repo/setting")
-}
-
-func Commits(ctx *middleware.Context, params martini.Params) {
-	brs, err := models.GetBranches(params["username"], params["reponame"])
-	if err != nil {
-		ctx.Handle(200, "repo.Commits", err)
-		return
-	} else if len(brs) == 0 {
-		ctx.Error(404)
-		return
-	}
-
-	ctx.Data["IsRepoToolbarCommits"] = true
-	commits, err := models.GetCommits(params["username"],
-		params["reponame"], params["branchname"])
-	if err != nil {
-		ctx.Error(404)
-		return
-	}
-	ctx.Data["Username"] = params["username"]
-	ctx.Data["Reponame"] = params["reponame"]
-	ctx.Data["CommitCount"] = commits.Len()
-	ctx.Data["Commits"] = commits
-	ctx.HTML(200, "repo/commits")
-}
-
-func Issues(ctx *middleware.Context) {
-	ctx.Data["IsRepoToolbarIssues"] = true
-	ctx.HTML(200, "repo/issues")
-}
-
-func Pulls(ctx *middleware.Context) {
-	ctx.Data["IsRepoToolbarPulls"] = true
-	ctx.HTML(200, "repo/pulls")
-}
-
-func Action(ctx *middleware.Context, params martini.Params) {
-	var err error
-	switch params["action"] {
-	case "watch":
-		err = models.WatchRepo(ctx.User.Id, ctx.Repo.Repository.Id, true)
-	case "unwatch":
-		err = models.WatchRepo(ctx.User.Id, ctx.Repo.Repository.Id, false)
-	}
-
-	if err != nil {
-		log.Error("repo.Action(%s): %v", params["action"], err)
-		ctx.JSON(200, map[string]interface{}{
-			"ok":  false,
-			"err": err.Error(),
-		})
-		return
-	}
-	ctx.JSON(200, map[string]interface{}{
-		"ok": true,
-	})
-}