2020-01-10 12:34:21 +03:00
// Copyright 2019 The Gitea 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 repository
import (
"container/list"
"fmt"
"time"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
api "code.gitea.io/gitea/modules/structs"
)
// PushCommit represents a commit in a push operation.
type PushCommit struct {
Sha1 string
Message string
AuthorEmail string
AuthorName string
CommitterEmail string
CommitterName string
Timestamp time . Time
}
// PushCommits represents list of commits in a push operation.
type PushCommits struct {
Len int
Commits [ ] * PushCommit
CompareURL string
avatars map [ string ] string
emailUsers map [ string ] * models . User
}
// NewPushCommits creates a new PushCommits object.
func NewPushCommits ( ) * PushCommits {
return & PushCommits {
avatars : make ( map [ string ] string ) ,
emailUsers : make ( map [ string ] * models . User ) ,
}
}
// ToAPIPayloadCommits converts a PushCommits object to
// api.PayloadCommit format.
func ( pc * PushCommits ) ToAPIPayloadCommits ( repoPath , repoLink string ) ( [ ] * api . PayloadCommit , error ) {
commits := make ( [ ] * api . PayloadCommit , len ( pc . Commits ) )
if pc . emailUsers == nil {
pc . emailUsers = make ( map [ string ] * models . User )
}
var err error
for i , commit := range pc . Commits {
authorUsername := ""
author , ok := pc . emailUsers [ commit . AuthorEmail ]
if ! ok {
author , err = models . GetUserByEmail ( commit . AuthorEmail )
if err == nil {
authorUsername = author . Name
pc . emailUsers [ commit . AuthorEmail ] = author
}
} else {
authorUsername = author . Name
}
committerUsername := ""
committer , ok := pc . emailUsers [ commit . CommitterEmail ]
if ! ok {
committer , err = models . GetUserByEmail ( commit . CommitterEmail )
if err == nil {
// TODO: check errors other than email not found.
committerUsername = committer . Name
pc . emailUsers [ commit . CommitterEmail ] = committer
}
} else {
committerUsername = committer . Name
}
fileStatus , err := git . GetCommitFileStatus ( repoPath , commit . Sha1 )
if err != nil {
return nil , fmt . Errorf ( "FileStatus [commit_sha1: %s]: %v" , commit . Sha1 , err )
}
commits [ i ] = & api . PayloadCommit {
ID : commit . Sha1 ,
Message : commit . Message ,
URL : fmt . Sprintf ( "%s/commit/%s" , repoLink , commit . Sha1 ) ,
Author : & api . PayloadUser {
Name : commit . AuthorName ,
Email : commit . AuthorEmail ,
UserName : authorUsername ,
} ,
Committer : & api . PayloadUser {
Name : commit . CommitterName ,
Email : commit . CommitterEmail ,
UserName : committerUsername ,
} ,
Added : fileStatus . Added ,
Removed : fileStatus . Removed ,
Modified : fileStatus . Modified ,
Timestamp : commit . Timestamp ,
}
}
return commits , nil
}
// AvatarLink tries to match user in database with e-mail
// in order to show custom avatar, and falls back to general avatar link.
func ( pc * PushCommits ) AvatarLink ( email string ) string {
if pc . avatars == nil {
pc . avatars = make ( map [ string ] string )
}
avatar , ok := pc . avatars [ email ]
if ok {
return avatar
}
2020-12-09 03:12:15 +03:00
size := models . DefaultAvatarPixelSize * models . AvatarRenderedSizeFactor
2020-01-10 12:34:21 +03:00
u , ok := pc . emailUsers [ email ]
if ! ok {
var err error
u , err = models . GetUserByEmail ( email )
if err != nil {
2020-12-09 03:12:15 +03:00
pc . avatars [ email ] = models . SizedAvatarLink ( email , size )
2020-01-10 12:34:21 +03:00
if ! models . IsErrUserNotExist ( err ) {
log . Error ( "GetUserByEmail: %v" , err )
return ""
}
} else {
pc . emailUsers [ email ] = u
}
}
if u != nil {
2020-12-09 03:12:15 +03:00
pc . avatars [ email ] = u . RealSizedAvatarLink ( size )
2020-01-10 12:34:21 +03:00
}
return pc . avatars [ email ]
}
// CommitToPushCommit transforms a git.Commit to PushCommit type.
func CommitToPushCommit ( commit * git . Commit ) * PushCommit {
return & PushCommit {
Sha1 : commit . ID . String ( ) ,
Message : commit . Message ( ) ,
AuthorEmail : commit . Author . Email ,
AuthorName : commit . Author . Name ,
CommitterEmail : commit . Committer . Email ,
CommitterName : commit . Committer . Name ,
Timestamp : commit . Author . When ,
}
}
// ListToPushCommits transforms a list.List to PushCommits type.
func ListToPushCommits ( l * list . List ) * PushCommits {
var commits [ ] * PushCommit
var actEmail string
for e := l . Front ( ) ; e != nil ; e = e . Next ( ) {
commit := e . Value . ( * git . Commit )
if actEmail == "" {
actEmail = commit . Committer . Email
}
commits = append ( commits , CommitToPushCommit ( commit ) )
}
return & PushCommits { l . Len ( ) , commits , "" , make ( map [ string ] string ) , make ( map [ string ] * models . User ) }
}