summaryrefslogtreecommitdiffstats
path: root/models
diff options
context:
space:
mode:
authorzhsso <zhssoge@gmail.com>2014-04-10 14:20:01 -0400
committerzhsso <zhssoge@gmail.com>2014-04-10 14:20:01 -0400
commitf3ed11d177d76bcb1850c6670c1516d25a66eb2c (patch)
tree4b825dc642cb6eb9a060e54bf8d69288fbee4904 /models
parentfde5b16332d5c4dc8246b899cd42d58b058f2bed (diff)
downloadgitea-f3ed11d177d76bcb1850c6670c1516d25a66eb2c.tar.gz
gitea-f3ed11d177d76bcb1850c6670c1516d25a66eb2c.zip
mistakes
Diffstat (limited to 'models')
-rw-r--r--models/access.go62
-rw-r--r--models/action.go135
-rw-r--r--models/git.go411
-rw-r--r--models/issue.go234
-rw-r--r--models/models.go131
-rw-r--r--models/models_test.go55
-rw-r--r--models/oauth2.go49
-rw-r--r--models/publickey.go228
-rw-r--r--models/repo.go647
-rw-r--r--models/user.go479
10 files changed, 0 insertions, 2431 deletions
diff --git a/models/access.go b/models/access.go
deleted file mode 100644
index 2c0900151f..0000000000
--- a/models/access.go
+++ /dev/null
@@ -1,62 +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 models
-
-import (
- "strings"
- "time"
-
- "github.com/lunny/xorm"
-)
-
-// Access types.
-const (
- AU_READABLE = iota + 1
- AU_WRITABLE
-)
-
-// Access represents the accessibility of user to repository.
-type Access struct {
- Id int64
- UserName string `xorm:"unique(s)"`
- RepoName string `xorm:"unique(s)"`
- Mode int `xorm:"unique(s)"`
- Created time.Time `xorm:"created"`
-}
-
-// AddAccess adds new access record.
-func AddAccess(access *Access) error {
- access.UserName = strings.ToLower(access.UserName)
- access.RepoName = strings.ToLower(access.RepoName)
- _, err := orm.Insert(access)
- return err
-}
-
-// UpdateAccess updates access information.
-func UpdateAccess(access *Access) error {
- access.UserName = strings.ToLower(access.UserName)
- access.RepoName = strings.ToLower(access.RepoName)
- _, err := orm.Id(access.Id).Update(access)
- return err
-}
-
-// UpdateAccess updates access information with session for rolling back.
-func UpdateAccessWithSession(sess *xorm.Session, access *Access) error {
- if _, err := sess.Id(access.Id).Update(access); err != nil {
- sess.Rollback()
- return err
- }
- return nil
-}
-
-// HasAccess returns true if someone can read or write to given repository.
-func HasAccess(userName, repoName string, mode int) (bool, error) {
- return orm.Get(&Access{
- Id: 0,
- UserName: strings.ToLower(userName),
- RepoName: strings.ToLower(repoName),
- Mode: mode,
- })
-}
diff --git a/models/action.go b/models/action.go
deleted file mode 100644
index a642a82c98..0000000000
--- a/models/action.go
+++ /dev/null
@@ -1,135 +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 models
-
-import (
- "encoding/json"
- "time"
-
- "github.com/gogits/gogs/modules/base"
- "github.com/gogits/gogs/modules/log"
-)
-
-// Operation types of user action.
-const (
- OP_CREATE_REPO = iota + 1
- OP_DELETE_REPO
- OP_STAR_REPO
- OP_FOLLOW_REPO
- OP_COMMIT_REPO
- OP_CREATE_ISSUE
- OP_PULL_REQUEST
- OP_TRANSFER_REPO
-)
-
-// Action represents user operation type and other information to repository.,
-// it implemented interface base.Actioner so that can be used in template render.
-type Action struct {
- Id int64
- UserId int64 // Receiver user id.
- OpType int // Operations: CREATE DELETE STAR ...
- ActUserId int64 // Action user id.
- ActUserName string // Action user name.
- ActEmail string
- RepoId int64
- RepoName string
- RefName string
- Content string `xorm:"TEXT"`
- Created time.Time `xorm:"created"`
-}
-
-func (a Action) GetOpType() int {
- return a.OpType
-}
-
-func (a Action) GetActUserName() string {
- return a.ActUserName
-}
-
-func (a Action) GetActEmail() string {
- return a.ActEmail
-}
-
-func (a Action) GetRepoName() string {
- return a.RepoName
-}
-
-func (a Action) GetBranch() string {
- return a.RefName
-}
-
-func (a Action) GetContent() string {
- return a.Content
-}
-
-// CommitRepoAction adds new action for committing repository.
-func CommitRepoAction(userId int64, userName, actEmail string,
- repoId int64, repoName string, refName string, commit *base.PushCommits) error {
- log.Trace("action.CommitRepoAction(start): %d/%s", userId, repoName)
-
- bs, err := json.Marshal(commit)
- if err != nil {
- log.Error("action.CommitRepoAction(json): %d/%s", userId, repoName)
- return err
- }
-
- if err = NotifyWatchers(&Action{ActUserId: userId, ActUserName: userName, ActEmail: actEmail,
- OpType: OP_COMMIT_REPO, Content: string(bs), RepoId: repoId, RepoName: repoName, RefName: refName}); err != nil {
- log.Error("action.CommitRepoAction(notify watchers): %d/%s", userId, repoName)
- return err
- }
-
- // Change repository bare status and update last updated time.
- repo, err := GetRepositoryByName(userId, repoName)
- if err != nil {
- log.Error("action.CommitRepoAction(GetRepositoryByName): %d/%s", userId, repoName)
- return err
- }
- repo.IsBare = false
- if err = UpdateRepository(repo); err != nil {
- log.Error("action.CommitRepoAction(UpdateRepository): %d/%s", userId, repoName)
- return err
- }
-
- log.Trace("action.CommitRepoAction(end): %d/%s", userId, repoName)
- return nil
-}
-
-// NewRepoAction adds new action for creating repository.
-func NewRepoAction(user *User, repo *Repository) (err error) {
- if err = NotifyWatchers(&Action{ActUserId: user.Id, ActUserName: user.Name, ActEmail: user.Email,
- OpType: OP_CREATE_REPO, RepoId: repo.Id, RepoName: repo.Name}); err != nil {
- log.Error("action.NewRepoAction(notify watchers): %d/%s", user.Id, repo.Name)
- return err
- }
-
- log.Trace("action.NewRepoAction: %s/%s", user.LowerName, repo.LowerName)
- return err
-}
-
-// TransferRepoAction adds new action for transfering repository.
-func TransferRepoAction(user, newUser *User, repo *Repository) (err error) {
- if err = NotifyWatchers(&Action{ActUserId: user.Id, ActUserName: user.Name, ActEmail: user.Email,
- OpType: OP_TRANSFER_REPO, RepoId: repo.Id, RepoName: repo.Name, Content: newUser.Name}); err != nil {
- log.Error("action.TransferRepoAction(notify watchers): %d/%s", user.Id, repo.Name)
- return err
- }
-
- log.Trace("action.TransferRepoAction: %s/%s", user.LowerName, repo.LowerName)
- return err
-}
-
-// GetFeeds returns action list of given user in given context.
-func GetFeeds(userid, offset int64, isProfile bool) ([]Action, error) {
- actions := make([]Action, 0, 20)
- sess := orm.Limit(20, int(offset)).Desc("id").Where("user_id=?", userid)
- if isProfile {
- sess.And("act_user_id=?", userid)
- } else {
- sess.And("act_user_id!=?", userid)
- }
- err := sess.Find(&actions)
- return actions, err
-}
diff --git a/models/git.go b/models/git.go
deleted file mode 100644
index 77b7ef2d7e..0000000000
--- a/models/git.go
+++ /dev/null
@@ -1,411 +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 models
-
-import (
- "bufio"
- "container/list"
- "fmt"
- "io"
- "os"
- "os/exec"
- "path"
- "strings"
-
- "github.com/gogits/git"
-
- "github.com/gogits/gogs/modules/base"
-)
-
-// RepoFile represents a file object in git repository.
-type RepoFile struct {
- *git.TreeEntry
- Path string
- Size int64
- Repo *git.Repository
- Commit *git.Commit
-}
-
-// LookupBlob returns the content of an object.
-func (file *RepoFile) LookupBlob() (*git.Blob, error) {
- if file.Repo == nil {
- return nil, ErrRepoFileNotLoaded
- }
-
- return file.Repo.LookupBlob(file.Id)
-}
-
-// GetBranches returns all branches of given repository.
-func GetBranches(userName, repoName string) ([]string, error) {
- repo, err := git.OpenRepository(RepoPath(userName, repoName))
- if err != nil {
- return nil, err
- }
-
- refs, err := repo.AllReferences()
- if err != nil {
- return nil, err
- }
-
- brs := make([]string, len(refs))
- for i, ref := range refs {
- brs[i] = ref.BranchName()
- }
- return brs, nil
-}
-
-// GetTags returns all tags of given repository.
-func GetTags(userName, repoName string) ([]string, error) {
- repo, err := git.OpenRepository(RepoPath(userName, repoName))
- if err != nil {
- return nil, err
- }
-
- refs, err := repo.AllTags()
- if err != nil {
- return nil, err
- }
-
- tags := make([]string, len(refs))
- for i, ref := range refs {
- tags[i] = ref.Name
- }
- return tags, nil
-}
-
-func IsBranchExist(userName, repoName, branchName string) bool {
- repo, err := git.OpenRepository(RepoPath(userName, repoName))
- if err != nil {
- return false
- }
- return repo.IsBranchExist(branchName)
-}
-
-func GetTargetFile(userName, repoName, branchName, commitId, rpath string) (*RepoFile, error) {
- repo, err := git.OpenRepository(RepoPath(userName, repoName))
- if err != nil {
- return nil, err
- }
-
- commit, err := repo.GetCommitOfBranch(branchName)
- if err != nil {
- commit, err = repo.GetCommit(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 GetReposFilesOfBranch(userName, repoName, branchName, rpath string) ([]*RepoFile, error) {
-// return getReposFiles(userName, repoName, commitId, rpath)
-// }
-
-// GetReposFiles returns a list of file object in given directory of repository.
-func GetReposFiles(userName, repoName, commitId, rpath string) ([]*RepoFile, error) {
- return getReposFiles(userName, repoName, commitId, rpath)
-}
-
-func getReposFiles(userName, repoName, commitId string, rpath string) ([]*RepoFile, error) {
- repopath := RepoPath(userName, repoName)
- repo, err := git.OpenRepository(repopath)
- if err != nil {
- return nil, err
- }
-
- commit, err := repo.GetCommit(commitId)
- if err != nil {
- return nil, err
- }
-
- var repodirs []*RepoFile
- var repofiles []*RepoFile
- commit.Tree.Walk(func(dirname string, entry *git.TreeEntry) int {
- if dirname == rpath {
- // TODO: size get method shoule be improved
- size, err := repo.ObjectSize(entry.Id)
- if err != nil {
- return 0
- }
-
- cmd := exec.Command("git", "log", "-1", "--pretty=format:%H", commitId, "--", path.Join(dirname, entry.Name))
- cmd.Dir = repopath
- out, err := cmd.Output()
- if err != nil {
- return 0
- }
- filecm, err := repo.GetCommit(string(out))
- if err != nil {
- return 0
- }
-
- rp := &RepoFile{
- entry,
- path.Join(dirname, entry.Name),
- size,
- repo,
- filecm,
- }
-
- if entry.IsFile() {
- repofiles = append(repofiles, rp)
- } else if entry.IsDir() {
- repodirs = append(repodirs, rp)
- }
- }
- return 0
- })
-
- return append(repodirs, repofiles...), nil
-}
-
-func GetCommit(userName, repoName, commitId string) (*git.Commit, error) {
- repo, err := git.OpenRepository(RepoPath(userName, repoName))
- if err != nil {
- return nil, err
- }
-
- return repo.GetCommit(commitId)
-}
-
-// GetCommitsByBranch returns all commits of given branch of repository.
-func GetCommitsByBranch(userName, repoName, branchName string) (*list.List, error) {
- repo, err := git.OpenRepository(RepoPath(userName, repoName))
- if err != nil {
- return nil, err
- }
- r, err := repo.LookupReference(fmt.Sprintf("refs/heads/%s", branchName))
- if err != nil {
- return nil, err
- }
- return r.AllCommits()
-}
-
-// GetCommitsByCommitId returns all commits of given commitId of repository.
-func GetCommitsByCommitId(userName, repoName, commitId string) (*list.List, error) {
- repo, err := git.OpenRepository(RepoPath(userName, repoName))
- if err != nil {
- return nil, err
- }
- oid, err := git.NewOidFromString(commitId)
- if err != nil {
- return nil, err
- }
- return repo.CommitsBefore(oid)
-}
-
-// Diff line types.
-const (
- DIFF_LINE_PLAIN = iota + 1
- DIFF_LINE_ADD
- DIFF_LINE_DEL
- DIFF_LINE_SECTION
-)
-
-const (
- DIFF_FILE_ADD = iota + 1
- DIFF_FILE_CHANGE
- DIFF_FILE_DEL
-)
-
-type DiffLine struct {
- LeftIdx int
- RightIdx int
- Type int
- Content string
-}
-
-func (d DiffLine) GetType() int {
- return d.Type
-}
-
-type DiffSection struct {
- Name string
- Lines []*DiffLine
-}
-
-type DiffFile struct {
- Name string
- Addition, Deletion int
- Type int
- Sections []*DiffSection
-}
-
-type Diff struct {
- TotalAddition, TotalDeletion int
- Files []*DiffFile
-}
-
-func (diff *Diff) NumFiles() int {
- return len(diff.Files)
-}
-
-const DIFF_HEAD = "diff --git "
-
-func ParsePatch(reader io.Reader) (*Diff, error) {
- scanner := bufio.NewScanner(reader)
- var (
- curFile *DiffFile
- curSection = &DiffSection{
- Lines: make([]*DiffLine, 0, 10),
- }
-
- leftLine, rightLine int
- )
-
- diff := &Diff{Files: make([]*DiffFile, 0)}
- var i int
- for scanner.Scan() {
- line := scanner.Text()
- // fmt.Println(i, line)
- if strings.HasPrefix(line, "+++ ") || strings.HasPrefix(line, "--- ") {
- continue
- }
-
- i = i + 1
- if line == "" {
- continue
- }
- if line[0] == ' ' {
- diffLine := &DiffLine{Type: DIFF_LINE_PLAIN, Content: line, LeftIdx: leftLine, RightIdx: rightLine}
- leftLine++
- rightLine++
- curSection.Lines = append(curSection.Lines, diffLine)
- continue
- } else if line[0] == '@' {
- curSection = &DiffSection{}
- curFile.Sections = append(curFile.Sections, curSection)
- ss := strings.Split(line, "@@")
- diffLine := &DiffLine{Type: DIFF_LINE_SECTION, Content: line}
- curSection.Lines = append(curSection.Lines, diffLine)
-
- // Parse line number.
- ranges := strings.Split(ss[len(ss)-2][1:], " ")
- leftLine, _ = base.StrTo(strings.Split(ranges[0], ",")[0][1:]).Int()
- rightLine, _ = base.StrTo(strings.Split(ranges[1], ",")[0]).Int()
- continue
- } else if line[0] == '+' {
- curFile.Addition++
- diff.TotalAddition++
- diffLine := &DiffLine{Type: DIFF_LINE_ADD, Content: line, RightIdx: rightLine}
- rightLine++
- curSection.Lines = append(curSection.Lines, diffLine)
- continue
- } else if line[0] == '-' {
- curFile.Deletion++
- diff.TotalDeletion++
- diffLine := &DiffLine{Type: DIFF_LINE_DEL, Content: line, LeftIdx: leftLine}
- if leftLine > 0 {
- leftLine++
- }
- curSection.Lines = append(curSection.Lines, diffLine)
- continue
- }
-
- // Get new file.
- if strings.HasPrefix(line, DIFF_HEAD) {
- fs := strings.Split(line[len(DIFF_HEAD):], " ")
- a := fs[0]
-
- curFile = &DiffFile{
- Name: a[strings.Index(a, "/")+1:],
- Type: DIFF_FILE_CHANGE,
- Sections: make([]*DiffSection, 0, 10),
- }
- diff.Files = append(diff.Files, curFile)
-
- // Check file diff type.
- for scanner.Scan() {
- switch {
- case strings.HasPrefix(scanner.Text(), "new file"):
- curFile.Type = DIFF_FILE_ADD
- case strings.HasPrefix(scanner.Text(), "deleted"):
- curFile.Type = DIFF_FILE_DEL
- case strings.HasPrefix(scanner.Text(), "index"):
- curFile.Type = DIFF_FILE_CHANGE
- }
- if curFile.Type > 0 {
- break
- }
- }
- }
- }
-
- return diff, nil
-}
-
-func GetDiff(repoPath, commitid string) (*Diff, error) {
- repo, err := git.OpenRepository(repoPath)
- if err != nil {
- return nil, err
- }
-
- commit, err := repo.GetCommit(commitid)
- if err != nil {
- return nil, err
- }
-
- // First commit of repository.
- if commit.ParentCount() == 0 {
- rd, wr := io.Pipe()
- go func() {
- cmd := exec.Command("git", "show", commitid)
- cmd.Dir = repoPath
- cmd.Stdout = wr
- cmd.Stdin = os.Stdin
- cmd.Stderr = os.Stderr
- cmd.Run()
- wr.Close()
- }()
- defer rd.Close()
- return ParsePatch(rd)
- }
-
- rd, wr := io.Pipe()
- go func() {
- cmd := exec.Command("git", "diff", commit.Parent(0).Oid.String(), commitid)
- cmd.Dir = repoPath
- cmd.Stdout = wr
- cmd.Stdin = os.Stdin
- cmd.Stderr = os.Stderr
- cmd.Run()
- wr.Close()
- }()
- defer rd.Close()
- return ParsePatch(rd)
-}
diff --git a/models/issue.go b/models/issue.go
deleted file mode 100644
index f14030df5e..0000000000
--- a/models/issue.go
+++ /dev/null
@@ -1,234 +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 models
-
-import (
- "errors"
- "strings"
- "time"
-
- "github.com/gogits/gogs/modules/base"
-)
-
-var (
- ErrIssueNotExist = errors.New("Issue does not exist")
-)
-
-// Issue represents an issue or pull request of repository.
-type Issue struct {
- Id int64
- Index int64 // Index in one repository.
- Name string
- RepoId int64 `xorm:"index"`
- Repo *Repository `xorm:"-"`
- PosterId int64
- Poster *User `xorm:"-"`
- MilestoneId int64
- AssigneeId int64
- IsPull bool // Indicates whether is a pull request or not.
- IsClosed bool
- Labels string `xorm:"TEXT"`
- Mentions string `xorm:"TEXT"`
- Content string `xorm:"TEXT"`
- RenderedContent string `xorm:"-"`
- 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, issueCount int, name, labels, content string, isPull bool) (issue *Issue, err error) {
- // TODO: find out mentions
- mentions := ""
-
- sess := orm.NewSession()
- defer sess.Close()
- sess.Begin()
-
- issue = &Issue{
- Index: int64(issueCount) + 1,
- Name: name,
- RepoId: repoId,
- PosterId: userId,
- MilestoneId: milestoneId,
- AssigneeId: assigneeId,
- IsPull: isPull,
- Labels: labels,
- Mentions: mentions,
- Content: content,
- }
- if _, err = sess.Insert(issue); err != nil {
- sess.Rollback()
- return nil, err
- }
-
- rawSql := "UPDATE `repository` SET num_issues = num_issues + 1 WHERE id = ?"
- if _, err = sess.Exec(rawSql, repoId); err != nil {
- sess.Rollback()
- return nil, err
- }
-
- if err = sess.Commit(); err != nil {
- sess.Rollback()
- return nil, err
- }
-
- return issue, nil
-}
-
-// GetIssueById returns issue object by given id.
-func GetIssueByIndex(repoId, index int64) (*Issue, error) {
- issue := &Issue{RepoId: repoId, Index: index}
- has, err := orm.Get(issue)
- if err != nil {
- return nil, err
- } else if !has {
- return nil, ErrIssueNotExist
- }
- return issue, nil
-}
-
-// 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)
-
- if repoId > 0 {
- sess.Where("repo_id=?", repoId).And("is_closed=?", isClosed)
- } else {
- sess.Where("is_closed=?", isClosed)
- }
-
- if userId > 0 {
- sess.And("assignee_id=?", userId)
- } else if posterId > 0 {
- sess.And("poster_id=?", posterId)
- } else if isMention {
- sess.And("mentions like '%$" + base.ToStr(userId) + "|%'")
- }
-
- if milestoneId > 0 {
- sess.And("milestone_id=?", milestoneId)
- }
-
- if len(labels) > 0 {
- for _, label := range strings.Split(labels, ",") {
- sess.And("mentions like '%$" + label + "|%'")
- }
- }
-
- switch sortType {
- case "oldest":
- sess.Asc("created")
- case "recentupdate":
- sess.Desc("updated")
- case "leastupdate":
- sess.Asc("updated")
- case "mostcomment":
- sess.Desc("num_comments")
- case "leastcomment":
- sess.Asc("num_comments")
- default:
- sess.Desc("created")
- }
-
- var issues []Issue
- err := sess.Find(&issues)
- return issues, err
-}
-
-// GetUserIssueCount returns the number of issues that were created by given user in repository.
-func GetUserIssueCount(userId, repoId int64) int64 {
- count, _ := orm.Where("poster_id=?", userId).And("repo_id=?", repoId).Count(new(Issue))
- return count
-}
-
-// UpdateIssue updates information of issue.
-func UpdateIssue(issue *Issue) error {
- _, err := orm.Id(issue.Id).AllCols().Update(issue)
- return 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"`
-}
-
-// Issue types.
-const (
- IT_PLAIN = iota // Pure comment.
- IT_REOPEN // Issue reopen status change prompt.
- IT_CLOSE // Issue close status change prompt.
-)
-
-// Comment represents a comment in commit and issue page.
-type Comment struct {
- Id int64
- Type int
- PosterId int64
- Poster *User `xorm:"-"`
- IssueId int64
- CommitId int64
- Line int64
- Content string
- Created time.Time `xorm:"created"`
-}
-
-// CreateComment creates comment of issue or commit.
-func CreateComment(userId, repoId, issueId, commitId, line int64, cmtType int, content string) error {
- sess := orm.NewSession()
- defer sess.Close()
- sess.Begin()
-
- if _, err := orm.Insert(&Comment{PosterId: userId, Type: cmtType, IssueId: issueId,
- CommitId: commitId, Line: line, Content: content}); err != nil {
- sess.Rollback()
- return err
- }
-
- // Check comment type.
- switch cmtType {
- case IT_PLAIN:
- rawSql := "UPDATE `issue` SET num_comments = num_comments + 1 WHERE id = ?"
- if _, err := sess.Exec(rawSql, issueId); err != nil {
- sess.Rollback()
- return err
- }
- case IT_REOPEN:
- rawSql := "UPDATE `repository` SET num_closed_issues = num_closed_issues - 1 WHERE id = ?"
- if _, err := sess.Exec(rawSql, repoId); err != nil {
- sess.Rollback()
- return err
- }
- case IT_CLOSE:
- rawSql := "UPDATE `repository` SET num_closed_issues = num_closed_issues + 1 WHERE id = ?"
- if _, err := sess.Exec(rawSql, repoId); err != nil {
- sess.Rollback()
- return err
- }
- }
- return sess.Commit()
-}
-
-// GetIssueComments returns list of comment by given issue id.
-func GetIssueComments(issueId int64) ([]Comment, error) {
- comments := make([]Comment, 0, 10)
- err := orm.Asc("created").Find(&comments, &Comment{IssueId: issueId})
- return comments, err
-}
diff --git a/models/models.go b/models/models.go
deleted file mode 100644
index ee96207d10..0000000000
--- a/models/models.go
+++ /dev/null
@@ -1,131 +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 models
-
-import (
- "fmt"
- "os"
- "path"
-
- _ "github.com/go-sql-driver/mysql"
- _ "github.com/lib/pq"
- "github.com/lunny/xorm"
- // _ "github.com/mattn/go-sqlite3"
-
- "github.com/gogits/gogs/modules/base"
-)
-
-var (
- orm *xorm.Engine
- tables []interface{}
-
- HasEngine bool
-
- DbCfg struct {
- Type, Host, Name, User, Pwd, Path, SslMode string
- }
-
- UseSQLite3 bool
-)
-
-func init() {
- tables = append(tables, new(User), new(PublicKey), new(Repository), new(Watch),
- new(Action), new(Access), new(Issue), new(Comment), new(Oauth2))
-}
-
-func LoadModelsConfig() {
- DbCfg.Type = base.Cfg.MustValue("database", "DB_TYPE")
- if DbCfg.Type == "sqlite3" {
- UseSQLite3 = true
- }
- DbCfg.Host = base.Cfg.MustValue("database", "HOST")
- DbCfg.Name = base.Cfg.MustValue("database", "NAME")
- DbCfg.User = base.Cfg.MustValue("database", "USER")
- DbCfg.Pwd = base.Cfg.MustValue("database", "PASSWD")
- DbCfg.SslMode = base.Cfg.MustValue("database", "SSL_MODE")
- DbCfg.Path = base.Cfg.MustValue("database", "PATH", "data/gogs.db")
-}
-
-func NewTestEngine(x *xorm.Engine) (err error) {
- switch DbCfg.Type {
- case "mysql":
- x, err = xorm.NewEngine("mysql", fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8",
- DbCfg.User, DbCfg.Pwd, DbCfg.Host, DbCfg.Name))
- case "postgres":
- x, err = xorm.NewEngine("postgres", fmt.Sprintf("user=%s password=%s dbname=%s sslmode=%s",
- DbCfg.User, DbCfg.Pwd, DbCfg.Name, DbCfg.SslMode))
- // case "sqlite3":
- // os.MkdirAll(path.Dir(DbCfg.Path), os.ModePerm)
- // x, err = xorm.NewEngine("sqlite3", DbCfg.Path)
- default:
- return fmt.Errorf("Unknown database type: %s", DbCfg.Type)
- }
- if err != nil {
- return fmt.Errorf("models.init(fail to conntect database): %v", err)
- }
- return x.Sync(tables...)
-}
-
-func SetEngine() (err error) {
- switch DbCfg.Type {
- case "mysql":
- orm, err = xorm.NewEngine("mysql", fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8",
- DbCfg.User, DbCfg.Pwd, DbCfg.Host, DbCfg.Name))
- case "postgres":
- orm, err = xorm.NewEngine("postgres", fmt.Sprintf("user=%s password=%s dbname=%s sslmode=%s",
- DbCfg.User, DbCfg.Pwd, DbCfg.Name, DbCfg.SslMode))
- case "sqlite3":
- os.MkdirAll(path.Dir(DbCfg.Path), os.ModePerm)
- orm, err = xorm.NewEngine("sqlite3", DbCfg.Path)
- default:
- return fmt.Errorf("Unknown database type: %s", DbCfg.Type)
- }
- if err != nil {
- return fmt.Errorf("models.init(fail to conntect database): %v", err)
- }
-
- // WARNNING: for serv command, MUST remove the output to os.stdout,
- // so use log file to instead print to stdout.
- execDir, _ := base.ExecDir()
- logPath := execDir + "/log/xorm.log"
- os.MkdirAll(path.Dir(logPath), os.ModePerm)
-
- f, err := os.Create(logPath)
- if err != nil {
- return fmt.Errorf("models.init(fail to create xorm.log): %v", err)
- }
- orm.Logger = f
-
- orm.ShowSQL = true
- orm.ShowDebug = true
- orm.ShowErr = true
- return nil
-}
-
-func NewEngine() (err error) {
- if err = SetEngine(); err != nil {
- return err
- }
- if err = orm.Sync(tables...); err != nil {
- return fmt.Errorf("sync database struct error: %v\n", err)
- }
- return nil
-}
-
-type Statistic struct {
- Counter struct {
- User, PublicKey, Repo, Watch, Action, Access int64
- }
-}
-
-func GetStatistic() (stats Statistic) {
- stats.Counter.User, _ = orm.Count(new(User))
- stats.Counter.PublicKey, _ = orm.Count(new(PublicKey))
- stats.Counter.Repo, _ = orm.Count(new(Repository))
- stats.Counter.Watch, _ = orm.Count(new(Watch))
- stats.Counter.Action, _ = orm.Count(new(Action))
- stats.Counter.Access, _ = orm.Count(new(Access))
- return
-}
diff --git a/models/models_test.go b/models/models_test.go
deleted file mode 100644
index b808f41d21..0000000000
--- a/models/models_test.go
+++ /dev/null
@@ -1,55 +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 models
-
-import (
- "fmt"
- "testing"
-
- "github.com/lunny/xorm"
- _ "github.com/mattn/go-sqlite3"
- . "github.com/smartystreets/goconvey/convey"
-
- "github.com/gogits/gogs/modules/base"
-)
-
-func init() {
- var err error
- orm, err = xorm.NewEngine("sqlite3", "./test.db")
- if err != nil {
- fmt.Println(err)
- }
-
- orm.ShowSQL = true
- orm.ShowDebug = true
-
- err = orm.Sync(&User{}, &Repository{})
- if err != nil {
- fmt.Println(err)
- }
-
- base.RepoRootPath = "test"
-}
-
-func TestCreateRepository(t *testing.T) {
- user := User{Id: 1, Name: "foobar", Type: UT_INDIVIDUAL}
- _, err := CreateRepository(&user, "test", "", "", "test repo desc", false, false)
- if err != nil {
- t.Error(err)
- }
-}
-
-func TestDeleteRepository(t *testing.T) {
- err := DeleteRepository(1, 1, "foobar")
- if err != nil {
- t.Error(err)
- }
-}
-
-func TestCommitRepoAction(t *testing.T) {
- Convey("Create a commit repository action", t, func() {
-
- })
-}
diff --git a/models/oauth2.go b/models/oauth2.go
deleted file mode 100644
index 45728b0d51..0000000000
--- a/models/oauth2.go
+++ /dev/null
@@ -1,49 +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 models
-
-import "errors"
-
-// OT: Oauth2 Type
-const (
- OT_GITHUB = iota + 1
- OT_GOOGLE
- OT_TWITTER
-)
-
-var (
- ErrOauth2RecordNotExists = errors.New("not exists oauth2 record")
- ErrOauth2NotAssociatedWithUser = errors.New("not associated with user")
-)
-
-type Oauth2 struct {
- Id int64
- Uid int64 // userId
- User *User `xorm:"-"`
- Type int `xorm:"pk unique(oauth)"` // twitter,github,google...
- Identity string `xorm:"pk unique(oauth)"` // id..
- Token string `xorm:"VARCHAR(200) not null"`
-}
-
-func AddOauth2(oa *Oauth2) (err error) {
- if _, err = orm.Insert(oa); err != nil {
- return err
- }
- return nil
-}
-
-func GetOauth2(identity string) (oa *Oauth2, err error) {
- oa = &Oauth2{Identity: identity}
- isExist, err := orm.Get(oa)
- if err != nil {
- return
- } else if !isExist {
- return nil, ErrOauth2RecordNotExists
- } else if oa.Uid == 0 {
- return oa, ErrOauth2NotAssociatedWithUser
- }
- oa.User, err = GetUserById(oa.Uid)
- return oa, err
-}
diff --git a/models/publickey.go b/models/publickey.go
deleted file mode 100644
index ed47ff209d..0000000000
--- a/models/publickey.go
+++ /dev/null
@@ -1,228 +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 models
-
-import (
- "bufio"
- "errors"
- "fmt"
- "io"
- "io/ioutil"
- "os"
- "os/exec"
- "path"
- "path/filepath"
- "strings"
- "sync"
- "time"
-
- "github.com/Unknwon/com"
-
- "github.com/gogits/gogs/modules/log"
-)
-
-const (
- // "### autogenerated by gitgos, DO NOT EDIT\n"
- TPL_PUBLICK_KEY = `command="%s serv key-%d",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty %s`
-)
-
-var (
- ErrKeyAlreadyExist = errors.New("Public key already exist")
-)
-
-var sshOpLocker = sync.Mutex{}
-
-var (
- sshPath string
- appPath string
-)
-
-// exePath returns the executable path.
-func exePath() (string, error) {
- file, err := exec.LookPath(os.Args[0])
- if err != nil {
- return "", err
- }
- return filepath.Abs(file)
-}
-
-// homeDir returns the home directory of current user.
-func homeDir() string {
- home, err := com.HomeDir()
- if err != nil {
- return "/"
- }
- return home
-}
-
-func init() {
- var err error
-
- appPath, err = exePath()
- if err != nil {
- fmt.Printf("publickey.init(fail to get app path): %v\n", err)
- os.Exit(2)
- }
-
- // Determine and create .ssh path.
- sshPath = filepath.Join(homeDir(), ".ssh")
- if err = os.MkdirAll(sshPath, os.ModePerm); err != nil {
- fmt.Printf("publickey.init(fail to create sshPath(%s)): %v\n", sshPath, err)
- os.Exit(2)
- }
-}
-
-// PublicKey represents a SSH key of user.
-type PublicKey struct {
- Id int64
- OwnerId int64 `xorm:"unique(s) index not null"`
- Name string `xorm:"unique(s) not null"`
- Fingerprint string
- Content string `xorm:"TEXT not null"`
- Created time.Time `xorm:"created"`
- Updated time.Time `xorm:"updated"`
-}
-
-// GenAuthorizedKey returns formatted public key string.
-func GenAuthorizedKey(keyId int64, key string) string {
- return fmt.Sprintf(TPL_PUBLICK_KEY+"\n", appPath, keyId, key)
-}
-
-// AddPublicKey adds new public key to database and SSH key file.
-func AddPublicKey(key *PublicKey) (err error) {
- // Check if public key name has been used.
- has, err := orm.Get(key)
- if err != nil {
- return err
- } else if has {
- return ErrKeyAlreadyExist
- }
-
- // Calculate fingerprint.
- tmpPath := strings.Replace(filepath.Join(os.TempDir(), fmt.Sprintf("%d", time.Now().Nanosecond()),
- "id_rsa.pub"), "\\", "/", -1)
- os.MkdirAll(path.Dir(tmpPath), os.ModePerm)
- if err = ioutil.WriteFile(tmpPath, []byte(key.Content), os.ModePerm); err != nil {
- return err
- }
- stdout, _, err := com.ExecCmd("ssh-keygen", "-l", "-f", tmpPath)
- if err != nil {
- return err
- } else if len(stdout) < 2 {
- return errors.New("Not enough output for calculating fingerprint")
- }
- key.Fingerprint = strings.Split(stdout, " ")[1]
-
- // Save SSH key.
- if _, err = orm.Insert(key); err != nil {
- return err
- }
- if err = SaveAuthorizedKeyFile(key); err != nil {
- if _, err2 := orm.Delete(key); err2 != nil {
- return err2
- }
- return err
- }
-
- return nil
-}
-
-func rewriteAuthorizedKeys(key *PublicKey, p, tmpP string) error {
- // Delete SSH key in SSH key file.
- sshOpLocker.Lock()
- defer sshOpLocker.Unlock()
-
- fr, err := os.Open(p)
- if err != nil {
- return err
- }
- defer fr.Close()
-
- fw, err := os.Create(tmpP)
- if err != nil {
- return err
- }
- defer fw.Close()
-
- buf := bufio.NewReader(fr)
- for {
- line, errRead := buf.ReadString('\n')
- line = strings.TrimSpace(line)
-
- if errRead != nil {
- if errRead != io.EOF {
- return errRead
- }
-
- // Reached end of file, if nothing to read then break,
- // otherwise handle the last line.
- if len(line) == 0 {
- break
- }
- }
-
- // Found the line and copy rest of file.
- if strings.Contains(line, fmt.Sprintf("key-%d", key.Id)) && strings.Contains(line, key.Content) {
- continue
- }
- // Still finding the line, copy the line that currently read.
- if _, err = fw.WriteString(line + "\n"); err != nil {
- return err
- }
-
- if errRead == io.EOF {
- break
- }
- }
- return nil
-}
-
-// DeletePublicKey deletes SSH key information both in database and authorized_keys file.
-func DeletePublicKey(key *PublicKey) (err error) {
- // Delete SSH key in database.
- has, err := orm.Id(key.Id).Get(key)
- if err != nil {
- return err
- } else if !has {
- return errors.New("Public key does not exist")
- }
- if _, err = orm.Delete(key); err != nil {
- return err
- }
-
- p := filepath.Join(sshPath, "authorized_keys")
- tmpP := filepath.Join(sshPath, "authorized_keys.tmp")
- log.Trace("ssh.DeletePublicKey(authorized_keys): %s", p)
-
- if err = rewriteAuthorizedKeys(key, p, tmpP); err != nil {
- return err
- } else if err = os.Remove(p); err != nil {
- return err
- }
- return os.Rename(tmpP, p)
-}
-
-// ListPublicKey returns a list of public keys that user has.
-func ListPublicKey(userId int64) ([]PublicKey, error) {
- keys := make([]PublicKey, 0)
- err := orm.Find(&keys, &PublicKey{OwnerId: userId})
- return keys, err
-}
-
-// SaveAuthorizedKeyFile writes SSH key content to SSH key file.
-func SaveAuthorizedKeyFile(key *PublicKey) error {
- sshOpLocker.Lock()
- defer sshOpLocker.Unlock()
-
- p := filepath.Join(sshPath, "authorized_keys")
- f, err := os.OpenFile(p, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
- if err != nil {
- return err
- }
- defer f.Close()
-
- _, err = f.WriteString(GenAuthorizedKey(key.Id, key.Content))
- return err
-}
diff --git a/models/repo.go b/models/repo.go
deleted file mode 100644
index 573e0f4e6f..0000000000
--- a/models/repo.go
+++ /dev/null
@@ -1,647 +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 models
-
-import (
- "errors"
- "fmt"
- "io/ioutil"
- "os"
- "os/exec"
- "path"
- "path/filepath"
- "strings"
- "time"
- "unicode/utf8"
-
- "github.com/Unknwon/cae/zip"
- "github.com/Unknwon/com"
-
- "github.com/gogits/git"
-
- "github.com/gogits/gogs/modules/base"
- "github.com/gogits/gogs/modules/log"
-)
-
-var (
- ErrRepoAlreadyExist = errors.New("Repository already exist")
- ErrRepoNotExist = errors.New("Repository does not exist")
- ErrRepoFileNotExist = errors.New("Target Repo file does not exist")
- ErrRepoNameIllegal = errors.New("Repository name contains illegal characters")
- ErrRepoFileNotLoaded = fmt.Errorf("repo file not loaded")
-)
-
-var (
- LanguageIgns, Licenses []string
-)
-
-func LoadRepoConfig() {
- LanguageIgns = strings.Split(base.Cfg.MustValue("repository", "LANG_IGNS"), "|")
- Licenses = strings.Split(base.Cfg.MustValue("repository", "LICENSES"), "|")
-}
-
-func NewRepoContext() {
- zip.Verbose = false
-
- // Check if server has basic git setting.
- stdout, _, err := com.ExecCmd("git", "config", "--get", "user.name")
- if err != nil {
- fmt.Printf("repo.init(fail to get git user.name): %v", err)
- os.Exit(2)
- } else if len(stdout) == 0 {
- if _, _, err = com.ExecCmd("git", "config", "--global", "user.email", "gogitservice@gmail.com"); err != nil {
- fmt.Printf("repo.init(fail to set git user.email): %v", err)
- os.Exit(2)
- } else if _, _, err = com.ExecCmd("git", "config", "--global", "user.name", "Gogs"); err != nil {
- fmt.Printf("repo.init(fail to set git user.name): %v", err)
- os.Exit(2)
- }
- }
-}
-
-// Repository represents a git repository.
-type Repository struct {
- Id int64
- OwnerId int64 `xorm:"unique(s)"`
- ForkId int64
- LowerName string `xorm:"unique(s) index not null"`
- Name string `xorm:"index not null"`
- Description string
- Website string
- NumWatches int
- NumStars int
- NumForks int
- NumIssues int
- NumReleases int `xorm:"NOT NULL"`
- NumClosedIssues int
- NumOpenIssues int `xorm:"-"`
- IsPrivate bool
- IsBare bool
- IsGoget bool
- Created time.Time `xorm:"created"`
- Updated time.Time `xorm:"updated"`
-}
-
-// IsRepositoryExist returns true if the repository with given name under user has already existed.
-func IsRepositoryExist(user *User, repoName string) (bool, error) {
- repo := Repository{OwnerId: user.Id}
- has, err := orm.Where("lower_name = ?", strings.ToLower(repoName)).Get(&repo)
- if err != nil {
- return has, err
- } else if !has {
- return false, nil
- }
-
- return com.IsDir(RepoPath(user.Name, repoName)), nil
-}
-
-var (
- illegalEquals = []string{"raw", "install", "api", "avatar", "user", "help", "stars", "issues", "pulls", "commits", "repo", "template", "admin"}
- illegalSuffixs = []string{".git"}
-)
-
-// IsLegalName returns false if name contains illegal characters.
-func IsLegalName(repoName string) bool {
- repoName = strings.ToLower(repoName)
- for _, char := range illegalEquals {
- if repoName == char {
- return false
- }
- }
- for _, char := range illegalSuffixs {
- if strings.HasSuffix(repoName, char) {
- return false
- }
- }
- return true
-}
-
-// CreateRepository creates a repository for given user or orgnaziation.
-func CreateRepository(user *User, repoName, desc, repoLang, license string, private bool, initReadme bool) (*Repository, error) {
- if !IsLegalName(repoName) {
- return nil, ErrRepoNameIllegal
- }
-
- isExist, err := IsRepositoryExist(user, repoName)
- if err != nil {
- return nil, err
- } else if isExist {
- return nil, ErrRepoAlreadyExist
- }
-
- repo := &Repository{
- OwnerId: user.Id,
- Name: repoName,
- LowerName: strings.ToLower(repoName),
- Description: desc,
- IsPrivate: private,
- IsBare: repoLang == "" && license == "" && !initReadme,
- }
- repoPath := RepoPath(user.Name, repoName)
-
- sess := orm.NewSession()
- defer sess.Close()
- sess.Begin()
-
- if _, err = sess.Insert(repo); err != nil {
- if err2 := os.RemoveAll(repoPath); err2 != nil {
- log.Error("repo.CreateRepository(repo): %v", err)
- return nil, errors.New(fmt.Sprintf(
- "delete repo directory %s/%s failed(1): %v", user.Name, repoName, err2))
- }
- sess.Rollback()
- return nil, err
- }
-
- access := Access{
- UserName: user.LowerName,
- RepoName: strings.ToLower(path.Join(user.Name, repo.Name)),
- Mode: AU_WRITABLE,
- }
- if _, err = sess.Insert(&access); err != nil {
- sess.Rollback()
- if err2 := os.RemoveAll(repoPath); err2 != nil {
- log.Error("repo.CreateRepository(access): %v", err)
- return nil, errors.New(fmt.Sprintf(
- "delete repo directory %s/%s failed(2): %v", user.Name, repoName, err2))
- }
- return nil, err
- }
-
- rawSql := "UPDATE `user` SET num_repos = num_repos + 1 WHERE id = ?"
- if _, err = sess.Exec(rawSql, user.Id); err != nil {
- sess.Rollback()
- if err2 := os.RemoveAll(repoPath); err2 != nil {
- log.Error("repo.CreateRepository(repo count): %v", err)
- return nil, errors.New(fmt.Sprintf(
- "delete repo directory %s/%s failed(3): %v", user.Name, repoName, err2))
- }
- return nil, err
- }
-
- if err = sess.Commit(); err != nil {
- sess.Rollback()
- if err2 := os.RemoveAll(repoPath); err2 != nil {
- log.Error("repo.CreateRepository(commit): %v", err)
- return nil, errors.New(fmt.Sprintf(
- "delete repo directory %s/%s failed(3): %v", user.Name, repoName, err2))
- }
- return nil, err
- }
-
- c := exec.Command("git", "update-server-info")
- c.Dir = repoPath
- if err = c.Run(); err != nil {
- log.Error("repo.CreateRepository(exec update-server-info): %v", err)
- }
-
- if err = NewRepoAction(user, repo); err != nil {
- log.Error("repo.CreateRepository(NewRepoAction): %v", err)
- }
-
- if err = WatchRepo(user.Id, repo.Id, true); err != nil {
- log.Error("repo.CreateRepository(WatchRepo): %v", err)
- }
-
- if err = initRepository(repoPath, user, repo, initReadme, repoLang, license); err != nil {
- return nil, err
- }
-
- return repo, nil
-}
-
-// extractGitBareZip extracts git-bare.zip to repository path.
-func extractGitBareZip(repoPath string) error {
- z, err := zip.Open("conf/content/git-bare.zip")
- if err != nil {
- fmt.Println("shi?")
- return err
- }
- defer z.Close()
-
- return z.ExtractTo(repoPath)
-}
-
-// initRepoCommit temporarily changes with work directory.
-func initRepoCommit(tmpPath string, sig *git.Signature) (err error) {
- var stderr string
- if _, stderr, err = com.ExecCmdDir(tmpPath, "git", "add", "--all"); err != nil {
- return err
- }
- if len(stderr) > 0 {
- log.Trace("stderr(1): %s", stderr)
- }
-
- if _, stderr, err = com.ExecCmdDir(tmpPath, "git", "commit", fmt.Sprintf("--author='%s <%s>'", sig.Name, sig.Email),
- "-m", "Init commit"); err != nil {
- return err
- }
- if len(stderr) > 0 {
- log.Trace("stderr(2): %s", stderr)
- }
-
- if _, stderr, err = com.ExecCmdDir(tmpPath, "git", "push", "origin", "master"); err != nil {
- return err
- }
- if len(stderr) > 0 {
- log.Trace("stderr(3): %s", stderr)
- }
- return nil
-}
-
-func createHookUpdate(hookPath, content string) error {
- pu, err := os.OpenFile(hookPath, os.O_CREATE|os.O_WRONLY, 0777)
- if err != nil {
- return err
- }
- defer pu.Close()
-
- _, err = pu.WriteString(content)
- return err
-}
-
-// SetRepoEnvs sets environment variables for command update.
-func SetRepoEnvs(userId int64, userName, repoName string) {
- os.Setenv("userId", base.ToStr(userId))
- os.Setenv("userName", userName)
- os.Setenv("repoName", repoName)
-}
-
-// InitRepository initializes README and .gitignore if needed.
-func initRepository(f string, user *User, repo *Repository, initReadme bool, repoLang, license string) error {
- repoPath := RepoPath(user.Name, repo.Name)
-
- // Create bare new repository.
- if err := extractGitBareZip(repoPath); err != nil {
- return err
- }
-
- // hook/post-update
- if err := createHookUpdate(filepath.Join(repoPath, "hooks", "update"),
- fmt.Sprintf("#!/usr/bin/env bash\n%s update $1 $2 $3\n",
- strings.Replace(appPath, "\\", "/", -1))); err != nil {
- return err
- }
-
- // Initialize repository according to user's choice.
- fileName := map[string]string{}
- if initReadme {
- fileName["readme"] = "README.md"
- }
- if repoLang != "" {
- fileName["gitign"] = ".gitignore"
- }
- if license != "" {
- fileName["license"] = "LICENSE"
- }
-
- // Clone to temprory path and do the init commit.
- tmpDir := filepath.Join(os.TempDir(), fmt.Sprintf("%d", time.Now().Nanosecond()))
- os.MkdirAll(tmpDir, os.ModePerm)
-
- if _, _, err := com.ExecCmd("git", "clone", repoPath, tmpDir); err != nil {
- return err
- }
-
- // README
- if initReadme {
- defaultReadme := repo.Name + "\n" + strings.Repeat("=",
- utf8.RuneCountInString(repo.Name)) + "\n\n" + repo.Description
- if err := ioutil.WriteFile(filepath.Join(tmpDir, fileName["readme"]),
- []byte(defaultReadme), 0644); err != nil {
- return err
- }
- }
-
- // .gitignore
- if repoLang != "" {
- filePath := "conf/gitignore/" + repoLang
- if com.IsFile(filePath) {
- if _, err := com.Copy(filePath,
- filepath.Join(tmpDir, fileName["gitign"])); err != nil {
- return err
- }
- }
- }
-
- // LICENSE
- if license != "" {
- filePath := "conf/license/" + license
- if com.IsFile(filePath) {
- if _, err := com.Copy(filePath,
- filepath.Join(tmpDir, fileName["license"])); err != nil {
- return err
- }
- }
- }
-
- if len(fileName) == 0 {
- return nil
- }
-
- SetRepoEnvs(user.Id, user.Name, repo.Name)
-
- // Apply changes and commit.
- return initRepoCommit(tmpDir, user.NewGitSig())
-}
-
-// UserRepo reporesents a repository with user name.
-type UserRepo struct {
- *Repository
- UserName string
-}
-
-// GetRepos returns given number of repository objects with offset.
-func GetRepos(num, offset int) ([]UserRepo, error) {
- repos := make([]Repository, 0, num)
- if err := orm.Limit(num, offset).Asc("id").Find(&repos); err != nil {
- return nil, err
- }
-
- urepos := make([]UserRepo, len(repos))
- for i := range repos {
- urepos[i].Repository = &repos[i]
- u := new(User)
- has, err := orm.Id(urepos[i].Repository.OwnerId).Get(u)
- if err != nil {
- return nil, err
- } else if !has {
- return nil, ErrUserNotExist
- }
- urepos[i].UserName = u.Name
- }
-
- return urepos, nil
-}
-
-func RepoPath(userName, repoName string) string {
- return filepath.Join(UserPath(userName), strings.ToLower(repoName)+".git")
-}
-
-// TransferOwnership transfers all corresponding setting from old user to new one.
-func TransferOwnership(user *User, newOwner string, repo *Repository) (err error) {
- newUser, err := GetUserByName(newOwner)
- if err != nil {
- return err
- }
-
- // Update accesses.
- accesses := make([]Access, 0, 10)
- if err = orm.Find(&accesses, &Access{RepoName: user.LowerName + "/" + repo.LowerName}); err != nil {
- return err
- }
-
- sess := orm.NewSession()
- defer sess.Close()
- if err = sess.Begin(); err != nil {
- return err
- }
-
- for i := range accesses {
- accesses[i].RepoName = newUser.LowerName + "/" + repo.LowerName
- if accesses[i].UserName == user.LowerName {
- accesses[i].UserName = newUser.LowerName
- }
- if err = UpdateAccessWithSession(sess, &accesses[i]); err != nil {
- return err
- }
- }
-
- // Update repository.
- repo.OwnerId = newUser.Id
- if _, err := sess.Id(repo.Id).Update(repo); err != nil {
- sess.Rollback()
- return err
- }
-
- // Update user repository number.
- rawSql := "UPDATE `user` SET num_repos = num_repos + 1 WHERE id = ?"
- if _, err = sess.Exec(rawSql, newUser.Id); err != nil {
- sess.Rollback()
- return err
- }
- rawSql = "UPDATE `user` SET num_repos = num_repos - 1 WHERE id = ?"
- if _, err = sess.Exec(rawSql, user.Id); err != nil {
- sess.Rollback()
- return err
- }
-
- // Add watch of new owner to repository.
- if !IsWatching(newUser.Id, repo.Id) {
- if err = WatchRepo(newUser.Id, repo.Id, true); err != nil {
- sess.Rollback()
- return err
- }
- }
-
- if err = TransferRepoAction(user, newUser, repo); err != nil {
- sess.Rollback()
- return err
- }
-
- // Change repository directory name.
- if err = os.Rename(RepoPath(user.Name, repo.Name), RepoPath(newUser.Name, repo.Name)); err != nil {
- sess.Rollback()
- return err
- }
-
- return sess.Commit()
-}
-
-// ChangeRepositoryName changes all corresponding setting from old repository name to new one.
-func ChangeRepositoryName(userName, oldRepoName, newRepoName string) (err error) {
- // Update accesses.
- accesses := make([]Access, 0, 10)
- if err = orm.Find(&accesses, &Access{RepoName: strings.ToLower(userName + "/" + oldRepoName)}); err != nil {
- return err
- }
-
- sess := orm.NewSession()
- defer sess.Close()
- if err = sess.Begin(); err != nil {
- return err
- }
-
- for i := range accesses {
- accesses[i].RepoName = userName + "/" + newRepoName
- if err = UpdateAccessWithSession(sess, &accesses[i]); err != nil {
- return err
- }
- }
-
- // Change repository directory name.
- if err = os.Rename(RepoPath(userName, oldRepoName), RepoPath(userName, newRepoName)); err != nil {
- sess.Rollback()
- return err
- }
-
- return sess.Commit()
-}
-
-func UpdateRepository(repo *Repository) error {
- repo.LowerName = strings.ToLower(repo.Name)
-
- if len(repo.Description) > 255 {
- repo.Description = repo.Description[:255]
- }
- if len(repo.Website) > 255 {
- repo.Website = repo.Website[:255]
- }
- _, err := orm.Id(repo.Id).AllCols().Update(repo)
- return err
-}
-
-// DeleteRepository deletes a repository for a user or orgnaztion.
-func DeleteRepository(userId, repoId int64, userName string) (err error) {
- repo := &Repository{Id: repoId, OwnerId: userId}
- has, err := orm.Get(repo)
- if err != nil {
- return err
- } else if !has {
- return ErrRepoNotExist
- }
-
- sess := orm.NewSession()
- defer sess.Close()
- if err = sess.Begin(); err != nil {
- return err
- }
- if _, err = sess.Delete(&Repository{Id: repoId}); err != nil {
- sess.Rollback()
- return err
- }
- if _, err := sess.Delete(&Access{RepoName: strings.ToLower(path.Join(userName, repo.Name))}); err != nil {
- sess.Rollback()
- return err
- }
- rawSql := "UPDATE `user` SET num_repos = num_repos - 1 WHERE id = ?"
- if _, err = sess.Exec(rawSql, userId); err != nil {
- sess.Rollback()
- return err
- }
- if _, err = sess.Delete(&Watch{RepoId: repoId}); err != nil {
- sess.Rollback()
- return err
- }
- if err = sess.Commit(); err != nil {
- sess.Rollback()
- return err
- }
- if err = os.RemoveAll(RepoPath(userName, repo.Name)); err != nil {
- // TODO: log and delete manully
- log.Error("delete repo %s/%s failed: %v", userName, repo.Name, err)
- return err
- }
- return nil
-}
-
-// GetRepositoryByName returns the repository by given name under user if exists.
-func GetRepositoryByName(userId int64, repoName string) (*Repository, error) {
- repo := &Repository{
- OwnerId: userId,
- LowerName: strings.ToLower(repoName),
- }
- has, err := orm.Get(repo)
- if err != nil {
- return nil, err
- } else if !has {
- return nil, ErrRepoNotExist
- }
- return repo, err
-}
-
-// GetRepositoryById returns the repository by given id if exists.
-func GetRepositoryById(id int64) (*Repository, error) {
- repo := &Repository{}
- has, err := orm.Id(id).Get(repo)
- if err != nil {
- return nil, err
- } else if !has {
- return nil, ErrRepoNotExist
- }
- return repo, err
-}
-
-// GetRepositories returns the list of repositories of given user.
-func GetRepositories(user *User) ([]Repository, error) {
- repos := make([]Repository, 0, 10)
- err := orm.Desc("updated").Find(&repos, &Repository{OwnerId: user.Id})
- return repos, err
-}
-
-func GetRepositoryCount(user *User) (int64, error) {
- return orm.Count(&Repository{OwnerId: user.Id})
-}
-
-// Watch is connection request for receiving repository notifycation.
-type Watch struct {
- Id int64
- RepoId int64 `xorm:"UNIQUE(watch)"`
- UserId int64 `xorm:"UNIQUE(watch)"`
-}
-
-// Watch or unwatch repository.
-func WatchRepo(userId, repoId int64, watch bool) (err error) {
- if watch {
- if _, err = orm.Insert(&Watch{RepoId: repoId, UserId: userId}); err != nil {
- return err
- }
-
- rawSql := "UPDATE `repository` SET num_watches = num_watches + 1 WHERE id = ?"
- _, err = orm.Exec(rawSql, repoId)
- } else {
- if _, err = orm.Delete(&Watch{0, repoId, userId}); err != nil {
- return err
- }
- rawSql := "UPDATE `repository` SET num_watches = num_watches - 1 WHERE id = ?"
- _, err = orm.Exec(rawSql, repoId)
- }
- return err
-}
-
-// GetWatches returns all watches of given repository.
-func GetWatches(repoId int64) ([]Watch, error) {
- watches := make([]Watch, 0, 10)
- err := orm.Find(&watches, &Watch{RepoId: repoId})
- return watches, err
-}
-
-// NotifyWatchers creates batch of actions for every watcher.
-func NotifyWatchers(act *Action) error {
- // Add feeds for user self and all watchers.
- watches, err := GetWatches(act.RepoId)
- if err != nil {
- return errors.New("repo.NotifyWatchers(get watches): " + err.Error())
- }
-
- // Add feed for actioner.
- act.UserId = act.ActUserId
- if _, err = orm.InsertOne(act); err != nil {
- return errors.New("repo.NotifyWatchers(create action): " + err.Error())
- }
-
- for i := range watches {
- if act.ActUserId == watches[i].UserId {
- continue
- }
-
- act.Id = 0
- act.UserId = watches[i].UserId
- if _, err = orm.InsertOne(act); err != nil {
- return errors.New("repo.NotifyWatchers(create action): " + err.Error())
- }
- }
- return nil
-}
-
-// IsWatching checks if user has watched given repository.
-func IsWatching(userId, repoId int64) bool {
- has, _ := orm.Get(&Watch{0, repoId, userId})
- return has
-}
-
-func ForkRepository(reposName string, userId int64) {
-
-}
diff --git a/models/user.go b/models/user.go
deleted file mode 100644
index b2fddd0a1d..0000000000
--- a/models/user.go
+++ /dev/null
@@ -1,479 +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 models
-
-import (
- "crypto/sha256"
- "encoding/hex"
- "errors"
- "fmt"
- "os"
- "path/filepath"
- "strings"
- "time"
-
- "github.com/gogits/git"
-
- "github.com/gogits/gogs/modules/base"
- "github.com/gogits/gogs/modules/log"
-)
-
-// User types.
-const (
- UT_INDIVIDUAL = iota + 1
- UT_ORGANIZATION
-)
-
-// Login types.
-const (
- LT_PLAIN = iota + 1
- LT_LDAP
-)
-
-var (
- ErrUserOwnRepos = errors.New("User still have ownership of repositories")
- ErrUserAlreadyExist = errors.New("User already exist")
- ErrUserNotExist = errors.New("User does not exist")
- ErrEmailAlreadyUsed = errors.New("E-mail already used")
- ErrUserNameIllegal = errors.New("User name contains illegal characters")
- ErrKeyNotExist = errors.New("Public key does not exist")
-)
-
-// User represents the object of individual and member of organization.
-type User struct {
- Id int64
- LowerName string `xorm:"unique not null"`
- Name string `xorm:"unique not null"`
- Email string `xorm:"unique not null"`
- Passwd string `xorm:"not null"`
- LoginType int
- Type int
- NumFollowers int
- NumFollowings int
- NumStars int
- NumRepos int
- Avatar string `xorm:"varchar(2048) not null"`
- AvatarEmail string `xorm:"not null"`
- Location string
- Website string
- IsActive bool
- IsAdmin bool
- Rands string `xorm:"VARCHAR(10)"`
- Salt string `xorm:"VARCHAR(10)"`
- Created time.Time `xorm:"created"`
- Updated time.Time `xorm:"updated"`
-}
-
-// HomeLink returns the user home page link.
-func (user *User) HomeLink() string {
- return "/user/" + user.Name
-}
-
-// AvatarLink returns the user gravatar link.
-func (user *User) AvatarLink() string {
- if base.Service.EnableCacheAvatar {
- return "/avatar/" + user.Avatar
- }
- return "http://1.gravatar.com/avatar/" + user.Avatar
-}
-
-// NewGitSig generates and returns the signature of given user.
-func (user *User) NewGitSig() *git.Signature {
- return &git.Signature{
- Name: user.Name,
- Email: user.Email,
- When: time.Now(),
- }
-}
-
-// EncodePasswd encodes password to safe format.
-func (user *User) EncodePasswd() {
- newPasswd := base.PBKDF2([]byte(user.Passwd), []byte(user.Salt), 10000, 50, sha256.New)
- user.Passwd = fmt.Sprintf("%x", newPasswd)
-}
-
-// Member represents user is member of organization.
-type Member struct {
- Id int64
- OrgId int64 `xorm:"unique(member) index"`
- UserId int64 `xorm:"unique(member)"`
-}
-
-// IsUserExist checks if given user name exist,
-// the user name should be noncased unique.
-func IsUserExist(name string) (bool, error) {
- if len(name) == 0 {
- return false, nil
- }
- return orm.Get(&User{LowerName: strings.ToLower(name)})
-}
-
-// IsEmailUsed returns true if the e-mail has been used.
-func IsEmailUsed(email string) (bool, error) {
- if len(email) == 0 {
- return false, nil
- }
- return orm.Get(&User{Email: email})
-}
-
-// return a user salt token
-func GetUserSalt() string {
- return base.GetRandomString(10)
-}
-
-// RegisterUser creates record of a new user.
-func RegisterUser(user *User) (*User, error) {
- if !IsLegalName(user.Name) {
- return nil, ErrUserNameIllegal
- }
-
- isExist, err := IsUserExist(user.Name)
- if err != nil {
- return nil, err
- } else if isExist {
- return nil, ErrUserAlreadyExist
- }
-
- isExist, err = IsEmailUsed(user.Email)
- if err != nil {
- return nil, err
- } else if isExist {
- return nil, ErrEmailAlreadyUsed
- }
-
- user.LowerName = strings.ToLower(user.Name)
- user.Avatar = base.EncodeMd5(user.Email)
- user.AvatarEmail = user.Email
- user.Rands = GetUserSalt()
- user.Salt = GetUserSalt()
- user.EncodePasswd()
- if _, err = orm.Insert(user); err != nil {
- return nil, err
- } else if err = os.MkdirAll(UserPath(user.Name), os.ModePerm); err != nil {
- if _, err := orm.Id(user.Id).Delete(&User{}); err != nil {
- return nil, errors.New(fmt.Sprintf(
- "both create userpath %s and delete table record faild: %v", user.Name, err))
- }
- return nil, err
- }
-
- if user.Id == 1 {
- user.IsAdmin = true
- user.IsActive = true
- _, err = orm.Id(user.Id).UseBool().Update(user)
- }
- return user, err
-}
-
-// GetUsers returns given number of user objects with offset.
-func GetUsers(num, offset int) ([]User, error) {
- users := make([]User, 0, num)
- err := orm.Limit(num, offset).Asc("id").Find(&users)
- return users, err
-}
-
-// get user by erify code
-func getVerifyUser(code string) (user *User) {
- if len(code) <= base.TimeLimitCodeLength {
- return nil
- }
-
- // use tail hex username query user
- hexStr := code[base.TimeLimitCodeLength:]
- if b, err := hex.DecodeString(hexStr); err == nil {
- if user, err = GetUserByName(string(b)); user != nil {
- return user
- }
- log.Error("user.getVerifyUser: %v", err)
- }
-
- return nil
-}
-
-// verify active code when active account
-func VerifyUserActiveCode(code string) (user *User) {
- minutes := base.Service.ActiveCodeLives
-
- if user = getVerifyUser(code); user != nil {
- // time limit code
- prefix := code[:base.TimeLimitCodeLength]
- data := base.ToStr(user.Id) + user.Email + user.LowerName + user.Passwd + user.Rands
-
- if base.VerifyTimeLimitCode(data, minutes, prefix) {
- return user
- }
- }
- return nil
-}
-
-// ChangeUserName changes all corresponding setting from old user name to new one.
-func ChangeUserName(user *User, newUserName string) (err error) {
- newUserName = strings.ToLower(newUserName)
-
- // Update accesses of user.
- accesses := make([]Access, 0, 10)
- if err = orm.Find(&accesses, &Access{UserName: user.LowerName}); err != nil {
- return err
- }
-
- sess := orm.NewSession()
- defer sess.Close()
- if err = sess.Begin(); err != nil {
- return err
- }
-
- for i := range accesses {
- accesses[i].UserName = newUserName
- if strings.HasPrefix(accesses[i].RepoName, user.LowerName+"/") {
- accesses[i].RepoName = strings.Replace(accesses[i].RepoName, user.LowerName, newUserName, 1)
- if err = UpdateAccessWithSession(sess, &accesses[i]); err != nil {
- return err
- }
- }
- }
-
- repos, err := GetRepositories(user)
- if err != nil {
- return err
- }
- for i := range repos {
- accesses = make([]Access, 0, 10)
- // Update accesses of user repository.
- if err = orm.Find(&accesses, &Access{RepoName: user.LowerName + "/" + repos[i].LowerName}); err != nil {
- return err
- }
-
- for j := range accesses {
- accesses[j].RepoName = newUserName + "/" + repos[i].LowerName
- if err = UpdateAccessWithSession(sess, &accesses[j]); err != nil {
- return err
- }
- }
- }
-
- // Change user directory name.
- if err = os.Rename(UserPath(user.LowerName), UserPath(newUserName)); err != nil {
- sess.Rollback()
- return err
- }
-
- return sess.Commit()
-}
-
-// UpdateUser updates user's information.
-func UpdateUser(user *User) (err error) {
- user.LowerName = strings.ToLower(user.Name)
-
- if len(user.Location) > 255 {
- user.Location = user.Location[:255]
- }
- if len(user.Website) > 255 {
- user.Website = user.Website[:255]
- }
-
- _, err = orm.Id(user.Id).AllCols().Update(user)
- return err
-}
-
-// DeleteUser completely deletes everything of the user.
-func DeleteUser(user *User) error {
- // Check ownership of repository.
- count, err := GetRepositoryCount(user)
- if err != nil {
- return errors.New("modesl.GetRepositories: " + err.Error())
- } else if count > 0 {
- return ErrUserOwnRepos
- }
-
- // TODO: check issues, other repos' commits
-
- // Delete all followers.
- if _, err = orm.Delete(&Follow{FollowId: user.Id}); err != nil {
- return err
- }
-
- // Delete all feeds.
- if _, err = orm.Delete(&Action{UserId: user.Id}); err != nil {
- return err
- }
-
- // Delete all watches.
- if _, err = orm.Delete(&Watch{UserId: user.Id}); err != nil {
- return err
- }
-
- // Delete all accesses.
- if _, err = orm.Delete(&Access{UserName: user.LowerName}); err != nil {
- return err
- }
-
- // Delete all SSH keys.
- keys := make([]PublicKey, 0, 10)
- if err = orm.Find(&keys, &PublicKey{OwnerId: user.Id}); err != nil {
- return err
- }
- for _, key := range keys {
- if err = DeletePublicKey(&key); err != nil {
- return err
- }
- }
-
- // Delete user directory.
- if err = os.RemoveAll(UserPath(user.Name)); err != nil {
- return err
- }
-
- _, err = orm.Delete(user)
- return err
-}
-
-// UserPath returns the path absolute path of user repositories.
-func UserPath(userName string) string {
- return filepath.Join(base.RepoRootPath, strings.ToLower(userName))
-}
-
-func GetUserByKeyId(keyId int64) (*User, error) {
- user := new(User)
- rawSql := "SELECT a.* FROM `user` AS a, public_key AS b WHERE a.id = b.owner_id AND b.id=?"
- has, err := orm.Sql(rawSql, keyId).Get(user)
- if err != nil {
- return nil, err
- } else if !has {
- err = errors.New("not exist key owner")
- return nil, err
- }
- return user, nil
-}
-
-// GetUserById returns the user object by given id if exists.
-func GetUserById(id int64) (*User, error) {
- user := new(User)
- has, err := orm.Id(id).Get(user)
- if err != nil {
- return nil, err
- }
- if !has {
- return nil, ErrUserNotExist
- }
- return user, nil
-}
-
-// GetUserByName returns the user object by given name if exists.
-func GetUserByName(name string) (*User, error) {
- if len(name) == 0 {
- return nil, ErrUserNotExist
- }
- user := &User{LowerName: strings.ToLower(name)}
- has, err := orm.Get(user)
- if err != nil {
- return nil, err
- } else if !has {
- return nil, ErrUserNotExist
- }
- return user, nil
-}
-
-// GetUserEmailsByNames returns a slice of e-mails corresponds to names.
-func GetUserEmailsByNames(names []string) []string {
- mails := make([]string, 0, len(names))
- for _, name := range names {
- u, err := GetUserByName(name)
- if err != nil {
- continue
- }
- mails = append(mails, u.Email)
- }
- return mails
-}
-
-// GetUserByEmail returns the user object by given e-mail if exists.
-func GetUserByEmail(email string) (*User, error) {
- if len(email) == 0 {
- return nil, ErrUserNotExist
- }
- user := &User{Email: strings.ToLower(email)}
- has, err := orm.Get(user)
- if err != nil {
- return nil, err
- } else if !has {
- return nil, ErrUserNotExist
- }
- return user, nil
-}
-
-// LoginUserPlain validates user by raw user name and password.
-func LoginUserPlain(name, passwd string) (*User, error) {
- user := User{LowerName: strings.ToLower(name)}
- has, err := orm.Get(&user)
- if err != nil {
- return nil, err
- } else if !has {
- return nil, ErrUserNotExist
- }
-
- newUser := &User{Passwd: passwd, Salt: user.Salt}
- newUser.EncodePasswd()
- if user.Passwd != newUser.Passwd {
- return nil, ErrUserNotExist
- }
- return &user, nil
-}
-
-// Follow is connection request for receiving user notifycation.
-type Follow struct {
- Id int64
- UserId int64 `xorm:"unique(follow)"`
- FollowId int64 `xorm:"unique(follow)"`
-}
-
-// FollowUser marks someone be another's follower.
-func FollowUser(userId int64, followId int64) (err error) {
- session := orm.NewSession()
- defer session.Close()
- session.Begin()
-
- if _, err = session.Insert(&Follow{UserId: userId, FollowId: followId}); err != nil {
- session.Rollback()
- return err
- }
-
- rawSql := "UPDATE `user` SET num_followers = num_followers + 1 WHERE id = ?"
- if _, err = session.Exec(rawSql, followId); err != nil {
- session.Rollback()
- return err
- }
-
- rawSql = "UPDATE `user` SET num_followings = num_followings + 1 WHERE id = ?"
- if _, err = session.Exec(rawSql, userId); err != nil {
- session.Rollback()
- return err
- }
- return session.Commit()
-}
-
-// UnFollowUser unmarks someone be another's follower.
-func UnFollowUser(userId int64, unFollowId int64) (err error) {
- session := orm.NewSession()
- defer session.Close()
- session.Begin()
-
- if _, err = session.Delete(&Follow{UserId: userId, FollowId: unFollowId}); err != nil {
- session.Rollback()
- return err
- }
-
- rawSql := "UPDATE `user` SET num_followers = num_followers - 1 WHERE id = ?"
- if _, err = session.Exec(rawSql, unFollowId); err != nil {
- session.Rollback()
- return err
- }
-
- rawSql = "UPDATE `user` SET num_followings = num_followings - 1 WHERE id = ?"
- if _, err = session.Exec(rawSql, userId); err != nil {
- session.Rollback()
- return err
- }
- return session.Commit()
-}