diff --git a/models/blockchain.go b/models/blockchain.go index a84636a5b..07f6d05bd 100755 --- a/models/blockchain.go +++ b/models/blockchain.go @@ -14,7 +14,8 @@ const ( ) type BlockChain struct { ID int64 `xorm:"pk autoincr"` - CommitID string `xorm:"INDEX NOT NULL"` + PrID int64 `xorm:"INDEX NOT NULL unique"` + CommitID string `xorm:"INDEX NOT NULL unique"` Contributor string `xorm:"INDEX NOT NULL"` ContractAddress string `xorm:"INDEX NOT NULL"` Status BlockChainCommitStatus `xorm:"INDEX NOT NULL DEFAULT 0"` @@ -45,6 +46,21 @@ func GetBlockChainByID(id int64) (*BlockChain, error) { return getBlockChainByID(x, id) } +func getBlockChainByPrID(e Engine, id int64) (*BlockChain, error) { + blockChain := new(BlockChain) + has, err := e.ID(id).Get(blockChain) + if err != nil { + return nil, err + } else if !has { + return nil, fmt.Errorf("get block_chain by pr_id failed(%d)", id) + } + return blockChain, nil +} + +func GetBlockChainByPrID(id int64) (*BlockChain, error) { + return getBlockChainByPrID(x, id) +} + func getBlockChainByCommitID(e Engine, commitID string) (*BlockChain, error) { blockChain := new(BlockChain) has, err := e.Where("commit_id = ?", commitID).Get(blockChain) diff --git a/models/pull.go b/models/pull.go old mode 100644 new mode 100755 index 9f1f48526..3942f5872 --- a/models/pull.go +++ b/models/pull.go @@ -36,6 +36,17 @@ const ( PullRequestStatusError ) +// PullRequestDifficulty defines pull request difficulty +type PullRequestDifficulty int + +// Enumerate all the pull request difficulty +const ( + PullRequestDifficultyZero PullRequestDifficulty = iota + PullRequestDifficultyOne + PullRequestDifficultyTwo + PullRequestDifficultyMax +) + // PullRequest represents relation between pull request and repositories. type PullRequest struct { ID int64 `xorm:"pk autoincr"` @@ -65,6 +76,10 @@ type PullRequest struct { MergedUnix timeutil.TimeStamp `xorm:"updated INDEX"` isHeadRepoLoaded bool `xorm:"-"` + + //block_chain + IsTransformed bool `xorm:"INDEX NOT NULL DEFAULT false"` + Difficulty PullRequestDifficulty `xorm:"INDEX NOT NULL DEFAULT 0"` } // MustHeadUserName returns the HeadRepo's username if failed return blank diff --git a/models/pull_list.go b/models/pull_list.go old mode 100644 new mode 100755 index 989de4689..8fb5c3f22 --- a/models/pull_list.go +++ b/models/pull_list.go @@ -170,3 +170,11 @@ func (prs PullRequestList) invalidateCodeComments(e Engine, doer *User, repo *gi func (prs PullRequestList) InvalidateCodeComments(doer *User, repo *git.Repository, branch string) error { return prs.invalidateCodeComments(x, doer, repo, branch) } + +func GetUnTransformedMergedPullRequests() ([]*PullRequest, error) { + prs := make([]*PullRequest, 0, 10) + return prs, x. + Where("has_merged = ? AND is_transformed = ?",true, false). + Join("INNER", "issue", "issue.id = pull_request.issue_id"). + Find(&prs) +} diff --git a/modules/auth/repo_form.go b/modules/auth/repo_form.go index 5e5638db1..709941d0f 100755 --- a/modules/auth/repo_form.go +++ b/modules/auth/repo_form.go @@ -369,6 +369,7 @@ type CreateIssueForm struct { AssigneeID int64 Content string Files []string + Difficulty int `form:"difficulty"` } // Validate validates the fields diff --git a/modules/blockchain/resty.go b/modules/blockchain/resty.go index 4a736a4f1..75374740d 100755 --- a/modules/blockchain/resty.go +++ b/modules/blockchain/resty.go @@ -123,19 +123,18 @@ func GetBalance(contractAddress, contributor string) (*GetBalanceResult, error) return &result, nil } -func Contribute(contractAddress, contributor, action, commitId string, codeLine int64) (*ContributeResult, error) { +func Contribute(contractAddress, contributor, commitId string, amount int64) (*ContributeResult, error) { client := getRestyClient() var result ContributeResult - amount := strconv.FormatInt(codeLine, 10) + strAmount := strconv.FormatInt(amount, 10) res, err := client.R(). SetHeader("Accept", "application/json"). SetQueryParams(map[string]string{ "contractAddress" : contractAddress, "contributor" : contributor, - "action" : action, "commitId": commitId, - "amount": amount, + "amount": strAmount, }). SetResult(&result). Get(setting.BlockChainHost + UrlContribute) diff --git a/modules/timer/timer.go b/modules/timer/timer.go index 60aaa7498..a05285495 100755 --- a/modules/timer/timer.go +++ b/modules/timer/timer.go @@ -19,9 +19,9 @@ func init() { c.AddFunc(specCheckRepoBlockChainSuccess, repo.HandleBlockChainUnSuccessRepos) specCheckUnTransformedActions := "*/1 * * * *" - c.AddFunc(specCheckUnTransformedActions, repo.HandleUnTransformedActions) + c.AddFunc(specCheckUnTransformedActions, repo.HandleBlockChainMergedPulls) - specCheckBlockChainCommitSuccess := "*/3 * * * *" - c.AddFunc(specCheckBlockChainCommitSuccess, repo.HandleBlockChainUnSuccessCommits) + //specCheckBlockChainCommitSuccess := "*/3 * * * *" + //c.AddFunc(specCheckBlockChainCommitSuccess, repo.HandleBlockChainUnSuccessCommits) c.Start() } diff --git a/routers/repo/blockchain.go b/routers/repo/blockchain.go index f6ced9194..60f8a7ddd 100755 --- a/routers/repo/blockchain.go +++ b/routers/repo/blockchain.go @@ -147,7 +147,7 @@ func HandleBlockChainUnSuccessCommits() { } for _, block_chain := range blockChains { - _, err = blockchain.Contribute(block_chain.ContractAddress, block_chain.Contributor, blockchain.ActionCommit, block_chain.CommitID, block_chain.Amount) + _, err = blockchain.Contribute(block_chain.ContractAddress, block_chain.Contributor, block_chain.CommitID, block_chain.Amount) if err != nil { log.Error("blockchain.Contribute(%s) failed:%v", block_chain.CommitID, err) } @@ -186,28 +186,27 @@ func HandleUnTransformedActions() { return } - isTransformed := true - for _, action := range actions { + isTransformed := true var content repository.PushCommits err = json.Unmarshal([]byte(action.Content), &content) if err != nil { isTransformed = false log.Error("json.Unmarshal action.Content(%s) failed:%v", action.Content, err) - break + continue } repo, err := models.GetRepositoryByID(action.RepoID) if err != nil { isTransformed = false log.Error("GetRepositoryByID(%d) failed:%v", action.RepoID, err) - break + continue } if repo.ContractAddress == "" { isTransformed = false log.Error("the repo(%s) has not been initialized in block_chain", repo.Name) - break + continue } for _, commit := range content.Commits { @@ -221,7 +220,7 @@ func HandleUnTransformedActions() { if err != nil { isTransformed = false log.Error("GetUserByName(%s) failed:%v", commit.CommitterName, err) - break + continue } blockChain := models.BlockChain{ @@ -237,13 +236,81 @@ func HandleUnTransformedActions() { if err != nil { isTransformed = false log.Error("InsertBlockChain(%s) failed:%v", commit.Sha1, err) - break + continue } } + if isTransformed { + action.IsTransformed = isTransformed + //todo: update is_transformed + //models.updateaction(action) + } + + } + + return +} + +func HandleBlockChainMergedPulls() { + prs, err := models.GetUnTransformedMergedPullRequests() + if err != nil { + log.Error("GetBlockChainUnSuccessUsers failed:", err.Error()) + return } - log.Info("", isTransformed) + for _, pr := range prs { + _, err = models.GetBlockChainByPrID(pr.ID) + if err == nil { + log.Info("the pr(%s) has been transformed", pr.MergedCommitID) + continue + } + + poster, err := models.GetUserByID(pr.Issue.PosterID) + if err != nil { + log.Error("GetUserByID(%s) failed:%v", pr.MergedCommitID, err) + continue + } + + if len(poster.PrivateKey) == 0 || len(poster.PublicKey) == 0 { + log.Error("the user has not been init in block_chain:", poster.Name) + continue + } + + repo, err := models.GetRepositoryByID(pr.HeadRepoID) + if err != nil { + log.Error("GetUserByID(%s) failed:%v", pr.MergedCommitID, err) + continue + } + + if len(repo.ContractAddress) == 0 { + log.Error("the repo(%s) has not been initialized in block_chain", repo.Name) + continue + } + + blockChain := models.BlockChain{ + Contributor : poster.PublicKey, + PrID : pr.ID, + CommitID : pr.MergedCommitID, + ContractAddress : repo.ContractAddress, + Status : models.BlockChainCommitInit, + Amount : int64(pr.Difficulty*100), + UserID : poster.ID, + RepoID : pr.HeadRepoID, + } + _, err = models.InsertBlockChain(&blockChain) + if err != nil { + log.Error("InsertBlockChain(%s) failed:%v", pr.MergedCommitID, err) + continue + } + + pr.IsTransformed = true + pr.UpdateCols("is_transformed") + + _, err = blockchain.Contribute(repo.ContractAddress, poster.PublicKey, pr.MergedCommitID, int64(pr.Difficulty*100)) + if err != nil { + log.Error("blockchain.Contribute(%s) failed:%v", pr.MergedCommitID, err) + } + } return } diff --git a/routers/repo/pull.go b/routers/repo/pull.go old mode 100644 new mode 100755 index a7af5bdb3..4883af638 --- a/routers/repo/pull.go +++ b/routers/repo/pull.go @@ -924,6 +924,11 @@ func CompareAndPullRequestPost(ctx *context.Context, form auth.CreateIssueForm) return } + if form.Difficulty > int(models.PullRequestDifficultyMax) || form.Difficulty < int(models.PullRequestDifficultyZero) { + ctx.RenderWithErr(ctx.Tr("the difficulty set error(0-3)"), tplCompareDiff, form) + return + } + pullIssue := &models.Issue{ RepoID: repo.ID, Title: form.Title, @@ -942,6 +947,7 @@ func CompareAndPullRequestPost(ctx *context.Context, form auth.CreateIssueForm) BaseRepo: repo, MergeBase: prInfo.MergeBase, Type: models.PullRequestGitea, + Difficulty: models.PullRequestDifficulty(form.Difficulty), } // FIXME: check error in the case two people send pull request at almost same time, give nice error prompt // instead of 500.