mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	Refactor struct's time to remove unnecessary memory usage (#3142)
* refactor struct's time to remove unnecessary memory usage * use AsTimePtr simple code * fix tests * fix time compare * fix template on gpg * use AddDuration instead of Add
This commit is contained in:
		@@ -18,6 +18,7 @@ import (
 | 
			
		||||
	"code.gitea.io/gitea/modules/base"
 | 
			
		||||
	"code.gitea.io/gitea/modules/log"
 | 
			
		||||
	"code.gitea.io/gitea/modules/setting"
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
	api "code.gitea.io/sdk/gitea"
 | 
			
		||||
 | 
			
		||||
	"github.com/Unknwon/com"
 | 
			
		||||
@@ -87,13 +88,7 @@ type Action struct {
 | 
			
		||||
	RefName     string
 | 
			
		||||
	IsPrivate   bool           `xorm:"INDEX NOT NULL DEFAULT false"`
 | 
			
		||||
	Content     string         `xorm:"TEXT"`
 | 
			
		||||
	Created     time.Time `xorm:"-"`
 | 
			
		||||
	CreatedUnix int64     `xorm:"INDEX created"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AfterLoad is invoked from XORM after setting the values of all fields of this object.
 | 
			
		||||
func (a *Action) AfterLoad() {
 | 
			
		||||
	a.Created = time.Unix(a.CreatedUnix, 0).Local()
 | 
			
		||||
	CreatedUnix util.TimeStamp `xorm:"INDEX created"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetOpType gets the ActionType of this action.
 | 
			
		||||
@@ -229,7 +224,7 @@ func (a *Action) GetContent() string {
 | 
			
		||||
 | 
			
		||||
// GetCreate returns the action creation time.
 | 
			
		||||
func (a *Action) GetCreate() time.Time {
 | 
			
		||||
	return a.Created
 | 
			
		||||
	return a.CreatedUnix.AsTime()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetIssueInfos returns a list of issues associated with
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,6 @@ package models
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/gitea/modules/log"
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
@@ -27,13 +26,7 @@ type Notice struct {
 | 
			
		||||
	ID          int64 `xorm:"pk autoincr"`
 | 
			
		||||
	Type        NoticeType
 | 
			
		||||
	Description string         `xorm:"TEXT"`
 | 
			
		||||
	Created     time.Time `xorm:"-"`
 | 
			
		||||
	CreatedUnix int64     `xorm:"INDEX created"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AfterLoad is invoked from XORM after setting the values of all fields of this object.
 | 
			
		||||
func (n *Notice) AfterLoad() {
 | 
			
		||||
	n.Created = time.Unix(n.CreatedUnix, 0).Local()
 | 
			
		||||
	CreatedUnix util.TimeStamp `xorm:"INDEX created"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TrStr returns a translation format string.
 | 
			
		||||
 
 | 
			
		||||
@@ -10,11 +10,11 @@ import (
 | 
			
		||||
	"mime/multipart"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	gouuid "github.com/satori/go.uuid"
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/gitea/modules/setting"
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Attachment represent a attachment of issue/comment/release.
 | 
			
		||||
@@ -26,14 +26,7 @@ type Attachment struct {
 | 
			
		||||
	CommentID     int64
 | 
			
		||||
	Name          string
 | 
			
		||||
	DownloadCount int64          `xorm:"DEFAULT 0"`
 | 
			
		||||
	Created       time.Time `xorm:"-"`
 | 
			
		||||
	CreatedUnix   int64     `xorm:"created"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AfterLoad is invoked from XORM after setting the value of a field of
 | 
			
		||||
// this object.
 | 
			
		||||
func (a *Attachment) AfterLoad() {
 | 
			
		||||
	a.Created = time.Unix(a.CreatedUnix, 0).Local()
 | 
			
		||||
	CreatedUnix   util.TimeStamp `xorm:"created"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IncreaseDownloadCount is update download count + 1
 | 
			
		||||
 
 | 
			
		||||
@@ -31,10 +31,8 @@ type ProtectedBranch struct {
 | 
			
		||||
	EnableWhitelist  bool
 | 
			
		||||
	WhitelistUserIDs []int64        `xorm:"JSON TEXT"`
 | 
			
		||||
	WhitelistTeamIDs []int64        `xorm:"JSON TEXT"`
 | 
			
		||||
	Created          time.Time `xorm:"-"`
 | 
			
		||||
	CreatedUnix      int64     `xorm:"created"`
 | 
			
		||||
	Updated          time.Time `xorm:"-"`
 | 
			
		||||
	UpdatedUnix      int64     `xorm:"updated"`
 | 
			
		||||
	CreatedUnix      util.TimeStamp `xorm:"created"`
 | 
			
		||||
	UpdatedUnix      util.TimeStamp `xorm:"updated"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsProtected returns if the branch is protected
 | 
			
		||||
@@ -203,13 +201,7 @@ type DeletedBranch struct {
 | 
			
		||||
	Commit      string         `xorm:"UNIQUE(s) NOT NULL"`
 | 
			
		||||
	DeletedByID int64          `xorm:"INDEX"`
 | 
			
		||||
	DeletedBy   *User          `xorm:"-"`
 | 
			
		||||
	Deleted     time.Time `xorm:"-"`
 | 
			
		||||
	DeletedUnix int64     `xorm:"INDEX created"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AfterLoad is invoked from XORM after setting the values of all fields of this object.
 | 
			
		||||
func (deletedBranch *DeletedBranch) AfterLoad() {
 | 
			
		||||
	deletedBranch.Deleted = time.Unix(deletedBranch.DeletedUnix, 0).Local()
 | 
			
		||||
	DeletedUnix util.TimeStamp `xorm:"INDEX created"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AddDeletedBranch adds a deleted branch to the database
 | 
			
		||||
 
 | 
			
		||||
@@ -17,6 +17,7 @@ import (
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/git"
 | 
			
		||||
	"code.gitea.io/gitea/modules/log"
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
 | 
			
		||||
	"github.com/go-xorm/xorm"
 | 
			
		||||
	"github.com/keybase/go-crypto/openpgp"
 | 
			
		||||
@@ -31,12 +32,9 @@ type GPGKey struct {
 | 
			
		||||
	KeyID             string         `xorm:"INDEX CHAR(16) NOT NULL"`
 | 
			
		||||
	PrimaryKeyID      string         `xorm:"CHAR(16)"`
 | 
			
		||||
	Content           string         `xorm:"TEXT NOT NULL"`
 | 
			
		||||
	Created           time.Time `xorm:"-"`
 | 
			
		||||
	CreatedUnix       int64
 | 
			
		||||
	Expired           time.Time `xorm:"-"`
 | 
			
		||||
	ExpiredUnix       int64
 | 
			
		||||
	Added             time.Time `xorm:"-"`
 | 
			
		||||
	AddedUnix         int64
 | 
			
		||||
	CreatedUnix       util.TimeStamp `xorm:"created"`
 | 
			
		||||
	ExpiredUnix       util.TimeStamp
 | 
			
		||||
	AddedUnix         util.TimeStamp
 | 
			
		||||
	SubsKey           []*GPGKey `xorm:"-"`
 | 
			
		||||
	Emails            []*EmailAddress
 | 
			
		||||
	CanSign           bool
 | 
			
		||||
@@ -47,17 +45,11 @@ type GPGKey struct {
 | 
			
		||||
 | 
			
		||||
// BeforeInsert will be invoked by XORM before inserting a record
 | 
			
		||||
func (key *GPGKey) BeforeInsert() {
 | 
			
		||||
	key.AddedUnix = time.Now().Unix()
 | 
			
		||||
	key.ExpiredUnix = key.Expired.Unix()
 | 
			
		||||
	key.CreatedUnix = key.Created.Unix()
 | 
			
		||||
	key.AddedUnix = util.TimeStampNow()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AfterLoad is invoked from XORM after setting the values of all fields of this object.
 | 
			
		||||
func (key *GPGKey) AfterLoad(session *xorm.Session) {
 | 
			
		||||
	key.Added = time.Unix(key.AddedUnix, 0).Local()
 | 
			
		||||
	key.Expired = time.Unix(key.ExpiredUnix, 0).Local()
 | 
			
		||||
	key.Created = time.Unix(key.CreatedUnix, 0).Local()
 | 
			
		||||
 | 
			
		||||
	err := session.Where("primary_key_id=?", key.KeyID).Find(&key.SubsKey)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Error(3, "Find Sub GPGkeys[%d]: %v", key.KeyID, err)
 | 
			
		||||
@@ -163,8 +155,8 @@ func parseSubGPGKey(ownerID int64, primaryID string, pubkey *packet.PublicKey, e
 | 
			
		||||
		KeyID:             pubkey.KeyIdString(),
 | 
			
		||||
		PrimaryKeyID:      primaryID,
 | 
			
		||||
		Content:           content,
 | 
			
		||||
		Created:           pubkey.CreationTime,
 | 
			
		||||
		Expired:           expiry,
 | 
			
		||||
		CreatedUnix:       util.TimeStamp(pubkey.CreationTime.Unix()),
 | 
			
		||||
		ExpiredUnix:       util.TimeStamp(expiry.Unix()),
 | 
			
		||||
		CanSign:           pubkey.CanSign(),
 | 
			
		||||
		CanEncryptComms:   pubkey.PubKeyAlgo.CanEncrypt(),
 | 
			
		||||
		CanEncryptStorage: pubkey.PubKeyAlgo.CanEncrypt(),
 | 
			
		||||
@@ -236,8 +228,8 @@ func parseGPGKey(ownerID int64, e *openpgp.Entity) (*GPGKey, error) {
 | 
			
		||||
		KeyID:             pubkey.KeyIdString(),
 | 
			
		||||
		PrimaryKeyID:      "",
 | 
			
		||||
		Content:           content,
 | 
			
		||||
		Created:           pubkey.CreationTime,
 | 
			
		||||
		Expired:           expiry,
 | 
			
		||||
		CreatedUnix:       util.TimeStamp(pubkey.CreationTime.Unix()),
 | 
			
		||||
		ExpiredUnix:       util.TimeStamp(expiry.Unix()),
 | 
			
		||||
		Emails:            emails,
 | 
			
		||||
		SubsKey:           subkeys,
 | 
			
		||||
		CanSign:           pubkey.CanSign(),
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,8 @@ package models
 | 
			
		||||
import (
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
 | 
			
		||||
	"github.com/stretchr/testify/assert"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -109,7 +111,7 @@ MkM/fdpyc2hY7Dl/+qFmN5MG5yGmMpQcX+RNNR222ibNC1D3wg==
 | 
			
		||||
	key := &GPGKey{
 | 
			
		||||
		KeyID:             pubkey.KeyIdString(),
 | 
			
		||||
		Content:           content,
 | 
			
		||||
		Created:           pubkey.CreationTime,
 | 
			
		||||
		CreatedUnix:       util.TimeStamp(pubkey.CreationTime.Unix()),
 | 
			
		||||
		CanSign:           pubkey.CanSign(),
 | 
			
		||||
		CanEncryptComms:   pubkey.PubKeyAlgo.CanEncrypt(),
 | 
			
		||||
		CanEncryptStorage: pubkey.PubKeyAlgo.CanEncrypt(),
 | 
			
		||||
@@ -119,7 +121,7 @@ MkM/fdpyc2hY7Dl/+qFmN5MG5yGmMpQcX+RNNR222ibNC1D3wg==
 | 
			
		||||
	cannotsignkey := &GPGKey{
 | 
			
		||||
		KeyID:             pubkey.KeyIdString(),
 | 
			
		||||
		Content:           content,
 | 
			
		||||
		Created:           pubkey.CreationTime,
 | 
			
		||||
		CreatedUnix:       util.TimeStamp(pubkey.CreationTime.Unix()),
 | 
			
		||||
		CanSign:           false,
 | 
			
		||||
		CanEncryptComms:   false,
 | 
			
		||||
		CanEncryptStorage: false,
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,6 @@ import (
 | 
			
		||||
	"path"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	api "code.gitea.io/sdk/gitea"
 | 
			
		||||
	"github.com/Unknwon/com"
 | 
			
		||||
@@ -45,31 +44,15 @@ type Issue struct {
 | 
			
		||||
	NumComments     int
 | 
			
		||||
	Ref             string
 | 
			
		||||
 | 
			
		||||
	Deadline     time.Time `xorm:"-"`
 | 
			
		||||
	DeadlineUnix int64     `xorm:"INDEX"`
 | 
			
		||||
	Created      time.Time `xorm:"-"`
 | 
			
		||||
	CreatedUnix  int64     `xorm:"INDEX created"`
 | 
			
		||||
	Updated      time.Time `xorm:"-"`
 | 
			
		||||
	UpdatedUnix  int64     `xorm:"INDEX updated"`
 | 
			
		||||
	DeadlineUnix util.TimeStamp `xorm:"INDEX"`
 | 
			
		||||
	CreatedUnix  util.TimeStamp `xorm:"INDEX created"`
 | 
			
		||||
	UpdatedUnix  util.TimeStamp `xorm:"INDEX updated"`
 | 
			
		||||
 | 
			
		||||
	Attachments []*Attachment `xorm:"-"`
 | 
			
		||||
	Comments    []*Comment    `xorm:"-"`
 | 
			
		||||
	Reactions   ReactionList  `xorm:"-"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BeforeUpdate is invoked from XORM before updating this object.
 | 
			
		||||
func (issue *Issue) BeforeUpdate() {
 | 
			
		||||
	issue.DeadlineUnix = issue.Deadline.Unix()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AfterLoad is invoked from XORM after setting the value of a field of
 | 
			
		||||
// this object.
 | 
			
		||||
func (issue *Issue) AfterLoad() {
 | 
			
		||||
	issue.Deadline = time.Unix(issue.DeadlineUnix, 0).Local()
 | 
			
		||||
	issue.Created = time.Unix(issue.CreatedUnix, 0).Local()
 | 
			
		||||
	issue.Updated = time.Unix(issue.UpdatedUnix, 0).Local()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (issue *Issue) loadRepo(e Engine) (err error) {
 | 
			
		||||
	if issue.Repo == nil {
 | 
			
		||||
		issue.Repo, err = getRepositoryByID(e, issue.RepoID)
 | 
			
		||||
@@ -307,8 +290,8 @@ func (issue *Issue) APIFormat() *api.Issue {
 | 
			
		||||
		Labels:   apiLabels,
 | 
			
		||||
		State:    issue.State(),
 | 
			
		||||
		Comments: issue.NumComments,
 | 
			
		||||
		Created:  issue.Created,
 | 
			
		||||
		Updated:  issue.Updated,
 | 
			
		||||
		Created:  issue.CreatedUnix.AsTime(),
 | 
			
		||||
		Updated:  issue.UpdatedUnix.AsTime(),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if issue.Milestone != nil {
 | 
			
		||||
@@ -322,7 +305,7 @@ func (issue *Issue) APIFormat() *api.Issue {
 | 
			
		||||
			HasMerged: issue.PullRequest.HasMerged,
 | 
			
		||||
		}
 | 
			
		||||
		if issue.PullRequest.HasMerged {
 | 
			
		||||
			apiIssue.PullRequest.Merged = &issue.PullRequest.Merged
 | 
			
		||||
			apiIssue.PullRequest.Merged = issue.PullRequest.MergedUnix.AsTimePtr()
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,6 @@ package models
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/Unknwon/com"
 | 
			
		||||
	"github.com/go-xorm/builder"
 | 
			
		||||
@@ -17,6 +16,7 @@ import (
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/gitea/modules/log"
 | 
			
		||||
	"code.gitea.io/gitea/modules/markup"
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// CommentType defines whether a comment is just a simple comment, an action (like close) or a reference.
 | 
			
		||||
@@ -98,10 +98,8 @@ type Comment struct {
 | 
			
		||||
	Content         string `xorm:"TEXT"`
 | 
			
		||||
	RenderedContent string `xorm:"-"`
 | 
			
		||||
 | 
			
		||||
	Created     time.Time `xorm:"-"`
 | 
			
		||||
	CreatedUnix int64     `xorm:"INDEX created"`
 | 
			
		||||
	Updated     time.Time `xorm:"-"`
 | 
			
		||||
	UpdatedUnix int64     `xorm:"INDEX updated"`
 | 
			
		||||
	CreatedUnix util.TimeStamp `xorm:"INDEX created"`
 | 
			
		||||
	UpdatedUnix util.TimeStamp `xorm:"INDEX updated"`
 | 
			
		||||
 | 
			
		||||
	// Reference issue in commit message
 | 
			
		||||
	CommitSHA string `xorm:"VARCHAR(40)"`
 | 
			
		||||
@@ -115,9 +113,6 @@ type Comment struct {
 | 
			
		||||
 | 
			
		||||
// AfterLoad is invoked from XORM after setting the values of all fields of this object.
 | 
			
		||||
func (c *Comment) AfterLoad(session *xorm.Session) {
 | 
			
		||||
	c.Created = time.Unix(c.CreatedUnix, 0).Local()
 | 
			
		||||
	c.Updated = time.Unix(c.UpdatedUnix, 0).Local()
 | 
			
		||||
 | 
			
		||||
	var err error
 | 
			
		||||
	c.Attachments, err = getAttachmentsByCommentID(session, c.ID)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
@@ -191,8 +186,8 @@ func (c *Comment) APIFormat() *api.Comment {
 | 
			
		||||
		IssueURL: c.IssueURL(),
 | 
			
		||||
		PRURL:    c.PRURL(),
 | 
			
		||||
		Body:     c.Content,
 | 
			
		||||
		Created:  c.Created,
 | 
			
		||||
		Updated:  c.Updated,
 | 
			
		||||
		Created:  c.CreatedUnix.AsTime(),
 | 
			
		||||
		Updated:  c.UpdatedUnix.AsTime(),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -33,9 +33,9 @@ func TestCreateComment(t *testing.T) {
 | 
			
		||||
	assert.EqualValues(t, "Hello", comment.Content)
 | 
			
		||||
	assert.EqualValues(t, issue.ID, comment.IssueID)
 | 
			
		||||
	assert.EqualValues(t, doer.ID, comment.PosterID)
 | 
			
		||||
	AssertInt64InRange(t, now, then, comment.CreatedUnix)
 | 
			
		||||
	AssertInt64InRange(t, now, then, int64(comment.CreatedUnix))
 | 
			
		||||
	AssertExistsAndLoadBean(t, comment) // assert actually added to DB
 | 
			
		||||
 | 
			
		||||
	updatedIssue := AssertExistsAndLoadBean(t, &Issue{ID: issue.ID}).(*Issue)
 | 
			
		||||
	AssertInt64InRange(t, now, then, updatedIssue.UpdatedUnix)
 | 
			
		||||
	AssertInt64InRange(t, now, then, int64(updatedIssue.UpdatedUnix))
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,9 +5,8 @@
 | 
			
		||||
package models
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/gitea/modules/setting"
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
	api "code.gitea.io/sdk/gitea"
 | 
			
		||||
 | 
			
		||||
	"github.com/go-xorm/xorm"
 | 
			
		||||
@@ -28,15 +27,13 @@ type Milestone struct {
 | 
			
		||||
	IsOverDue       bool `xorm:"-"`
 | 
			
		||||
 | 
			
		||||
	DeadlineString string `xorm:"-"`
 | 
			
		||||
	Deadline       time.Time `xorm:"-"`
 | 
			
		||||
	DeadlineUnix   int64
 | 
			
		||||
	ClosedDate     time.Time `xorm:"-"`
 | 
			
		||||
	ClosedDateUnix int64
 | 
			
		||||
	DeadlineUnix   util.TimeStamp
 | 
			
		||||
	ClosedDateUnix util.TimeStamp
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BeforeInsert is invoked from XORM before inserting an object of this type.
 | 
			
		||||
func (m *Milestone) BeforeInsert() {
 | 
			
		||||
	m.DeadlineUnix = m.Deadline.Unix()
 | 
			
		||||
	m.DeadlineUnix = util.TimeStampNow()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BeforeUpdate is invoked from XORM before updating this object.
 | 
			
		||||
@@ -46,26 +43,20 @@ func (m *Milestone) BeforeUpdate() {
 | 
			
		||||
	} else {
 | 
			
		||||
		m.Completeness = 0
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m.DeadlineUnix = m.Deadline.Unix()
 | 
			
		||||
	m.ClosedDateUnix = m.ClosedDate.Unix()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AfterLoad is invoked from XORM after setting the value of a field of
 | 
			
		||||
// this object.
 | 
			
		||||
func (m *Milestone) AfterLoad() {
 | 
			
		||||
	m.NumOpenIssues = m.NumIssues - m.NumClosedIssues
 | 
			
		||||
	m.Deadline = time.Unix(m.DeadlineUnix, 0).Local()
 | 
			
		||||
	if m.Deadline.Year() == 9999 {
 | 
			
		||||
	if m.DeadlineUnix.Year() == 9999 {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m.DeadlineString = m.Deadline.Format("2006-01-02")
 | 
			
		||||
	if time.Now().Local().After(m.Deadline) {
 | 
			
		||||
	m.DeadlineString = m.DeadlineUnix.Format("2006-01-02")
 | 
			
		||||
	if util.TimeStampNow() >= m.DeadlineUnix {
 | 
			
		||||
		m.IsOverDue = true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m.ClosedDate = time.Unix(m.ClosedDateUnix, 0).Local()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// State returns string representation of milestone status.
 | 
			
		||||
@@ -87,10 +78,10 @@ func (m *Milestone) APIFormat() *api.Milestone {
 | 
			
		||||
		ClosedIssues: m.NumClosedIssues,
 | 
			
		||||
	}
 | 
			
		||||
	if m.IsClosed {
 | 
			
		||||
		apiMilestone.Closed = &m.ClosedDate
 | 
			
		||||
		apiMilestone.Closed = m.ClosedDateUnix.AsTimePtr()
 | 
			
		||||
	}
 | 
			
		||||
	if m.Deadline.Year() < 9999 {
 | 
			
		||||
		apiMilestone.Deadline = &m.Deadline
 | 
			
		||||
	if m.DeadlineUnix.Year() < 9999 {
 | 
			
		||||
		apiMilestone.Deadline = m.DeadlineUnix.AsTimePtr()
 | 
			
		||||
	}
 | 
			
		||||
	return apiMilestone
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,7 @@ import (
 | 
			
		||||
	"testing"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
	api "code.gitea.io/sdk/gitea"
 | 
			
		||||
 | 
			
		||||
	"github.com/stretchr/testify/assert"
 | 
			
		||||
@@ -28,7 +29,7 @@ func TestMilestone_APIFormat(t *testing.T) {
 | 
			
		||||
		IsClosed:        false,
 | 
			
		||||
		NumOpenIssues:   5,
 | 
			
		||||
		NumClosedIssues: 6,
 | 
			
		||||
		Deadline:        time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC),
 | 
			
		||||
		DeadlineUnix:    util.TimeStamp(time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC).Unix()),
 | 
			
		||||
	}
 | 
			
		||||
	assert.Equal(t, api.Milestone{
 | 
			
		||||
		ID:           milestone.ID,
 | 
			
		||||
@@ -37,7 +38,7 @@ func TestMilestone_APIFormat(t *testing.T) {
 | 
			
		||||
		Description:  milestone.Content,
 | 
			
		||||
		OpenIssues:   milestone.NumOpenIssues,
 | 
			
		||||
		ClosedIssues: milestone.NumClosedIssues,
 | 
			
		||||
		Deadline:     &milestone.Deadline,
 | 
			
		||||
		Deadline:     milestone.DeadlineUnix.AsTimePtr(),
 | 
			
		||||
	}, *milestone.APIFormat())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,9 +7,9 @@ package models
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/gitea/modules/setting"
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
 | 
			
		||||
	"github.com/go-xorm/builder"
 | 
			
		||||
	"github.com/go-xorm/xorm"
 | 
			
		||||
@@ -23,13 +23,7 @@ type Reaction struct {
 | 
			
		||||
	CommentID   int64          `xorm:"INDEX UNIQUE(s)"`
 | 
			
		||||
	UserID      int64          `xorm:"INDEX UNIQUE(s) NOT NULL"`
 | 
			
		||||
	User        *User          `xorm:"-"`
 | 
			
		||||
	Created     time.Time `xorm:"-"`
 | 
			
		||||
	CreatedUnix int64     `xorm:"INDEX created"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AfterLoad is invoked from XORM after setting the values of all fields of this object.
 | 
			
		||||
func (s *Reaction) AfterLoad() {
 | 
			
		||||
	s.Created = time.Unix(s.CreatedUnix, 0).Local()
 | 
			
		||||
	CreatedUnix util.TimeStamp `xorm:"INDEX created"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FindReactionsOptions describes the conditions to Find reactions
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,8 @@ package models
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Stopwatch represents a stopwatch for time tracking.
 | 
			
		||||
@@ -14,19 +16,7 @@ type Stopwatch struct {
 | 
			
		||||
	ID          int64          `xorm:"pk autoincr"`
 | 
			
		||||
	IssueID     int64          `xorm:"INDEX"`
 | 
			
		||||
	UserID      int64          `xorm:"INDEX"`
 | 
			
		||||
	Created     time.Time `xorm:"-"`
 | 
			
		||||
	CreatedUnix int64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BeforeInsert will be invoked by XORM before inserting a record
 | 
			
		||||
// representing this object.
 | 
			
		||||
func (s *Stopwatch) BeforeInsert() {
 | 
			
		||||
	s.CreatedUnix = time.Now().Unix()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AfterLoad is invoked from XORM after setting the values of all fields of this object.
 | 
			
		||||
func (s *Stopwatch) AfterLoad() {
 | 
			
		||||
	s.Created = time.Unix(s.CreatedUnix, 0).Local()
 | 
			
		||||
	CreatedUnix util.TimeStamp `xorm:"created"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getStopwatch(e Engine, userID, issueID int64) (sw *Stopwatch, exists bool, err error) {
 | 
			
		||||
@@ -61,7 +51,7 @@ func CreateOrStopIssueStopwatch(user *User, issue *Issue) error {
 | 
			
		||||
	}
 | 
			
		||||
	if exists {
 | 
			
		||||
		// Create tracked time out of the time difference between start date and actual date
 | 
			
		||||
		timediff := time.Now().Unix() - sw.CreatedUnix
 | 
			
		||||
		timediff := time.Now().Unix() - int64(sw.CreatedUnix)
 | 
			
		||||
 | 
			
		||||
		// Create TrackedTime
 | 
			
		||||
		tt := &TrackedTime{
 | 
			
		||||
@@ -92,7 +82,6 @@ func CreateOrStopIssueStopwatch(user *User, issue *Issue) error {
 | 
			
		||||
		sw = &Stopwatch{
 | 
			
		||||
			UserID:  user.ID,
 | 
			
		||||
			IssueID: issue.ID,
 | 
			
		||||
			Created: time.Now(),
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if _, err := x.Insert(sw); err != nil {
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,8 @@ package models
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"testing"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
 | 
			
		||||
	"github.com/stretchr/testify/assert"
 | 
			
		||||
)
 | 
			
		||||
@@ -62,7 +63,7 @@ func TestCreateOrStopIssueStopwatch(t *testing.T) {
 | 
			
		||||
 | 
			
		||||
	assert.NoError(t, CreateOrStopIssueStopwatch(user3, issue1))
 | 
			
		||||
	sw := AssertExistsAndLoadBean(t, &Stopwatch{UserID: 3, IssueID: 1}).(*Stopwatch)
 | 
			
		||||
	assert.Equal(t, true, sw.Created.Before(time.Now()))
 | 
			
		||||
	assert.Equal(t, true, sw.CreatedUnix <= util.TimeStampNow())
 | 
			
		||||
 | 
			
		||||
	assert.NoError(t, CreateOrStopIssueStopwatch(user2, issue2))
 | 
			
		||||
	AssertNotExistsBean(t, &Stopwatch{UserID: 2, IssueID: 2})
 | 
			
		||||
 
 | 
			
		||||
@@ -166,5 +166,5 @@ func TestUpdateIssueCols(t *testing.T) {
 | 
			
		||||
	updatedIssue := AssertExistsAndLoadBean(t, &Issue{ID: issue.ID}).(*Issue)
 | 
			
		||||
	assert.EqualValues(t, newTitle, updatedIssue.Title)
 | 
			
		||||
	assert.EqualValues(t, prevContent, updatedIssue.Content)
 | 
			
		||||
	AssertInt64InRange(t, now, then, updatedIssue.UpdatedUnix)
 | 
			
		||||
	AssertInt64InRange(t, now, then, int64(updatedIssue.UpdatedUnix))
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,9 +4,7 @@
 | 
			
		||||
 | 
			
		||||
package models
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
import "code.gitea.io/gitea/modules/util"
 | 
			
		||||
 | 
			
		||||
// IssueWatch is connection request for receiving issue notification.
 | 
			
		||||
type IssueWatch struct {
 | 
			
		||||
@@ -14,32 +12,8 @@ type IssueWatch struct {
 | 
			
		||||
	UserID      int64          `xorm:"UNIQUE(watch) NOT NULL"`
 | 
			
		||||
	IssueID     int64          `xorm:"UNIQUE(watch) NOT NULL"`
 | 
			
		||||
	IsWatching  bool           `xorm:"NOT NULL"`
 | 
			
		||||
	Created     time.Time `xorm:"-"`
 | 
			
		||||
	CreatedUnix int64     `xorm:"NOT NULL"`
 | 
			
		||||
	Updated     time.Time `xorm:"-"`
 | 
			
		||||
	UpdatedUnix int64     `xorm:"NOT NULL"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BeforeInsert is invoked from XORM before inserting an object of this type.
 | 
			
		||||
func (iw *IssueWatch) BeforeInsert() {
 | 
			
		||||
	var (
 | 
			
		||||
		t = time.Now()
 | 
			
		||||
		u = t.Unix()
 | 
			
		||||
	)
 | 
			
		||||
	iw.Created = t
 | 
			
		||||
	iw.CreatedUnix = u
 | 
			
		||||
	iw.Updated = t
 | 
			
		||||
	iw.UpdatedUnix = u
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BeforeUpdate is invoked from XORM before updating an object of this type.
 | 
			
		||||
func (iw *IssueWatch) BeforeUpdate() {
 | 
			
		||||
	var (
 | 
			
		||||
		t = time.Now()
 | 
			
		||||
		u = t.Unix()
 | 
			
		||||
	)
 | 
			
		||||
	iw.Updated = t
 | 
			
		||||
	iw.UpdatedUnix = u
 | 
			
		||||
	CreatedUnix util.TimeStamp `xorm:"created NOT NULL"`
 | 
			
		||||
	UpdatedUnix util.TimeStamp `xorm:"updated NOT NULL"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CreateOrUpdateIssueWatch set watching for a user and issue
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,8 @@ package models
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// LFSMetaObject stores metadata for LFS tracked files.
 | 
			
		||||
@@ -12,8 +13,7 @@ type LFSMetaObject struct {
 | 
			
		||||
	Size         int64          `xorm:"NOT NULL"`
 | 
			
		||||
	RepositoryID int64          `xorm:"UNIQUE(s) INDEX NOT NULL"`
 | 
			
		||||
	Existing     bool           `xorm:"-"`
 | 
			
		||||
	Created      time.Time `xorm:"-"`
 | 
			
		||||
	CreatedUnix  int64     `xorm:"created"`
 | 
			
		||||
	CreatedUnix  util.TimeStamp `xorm:"created"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// LFSTokenResponse defines the JSON structure in which the JWT token is stored.
 | 
			
		||||
@@ -105,8 +105,3 @@ func (repo *Repository) RemoveLFSMetaObjectByOid(oid string) error {
 | 
			
		||||
 | 
			
		||||
	return sess.Commit()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AfterLoad stores the LFSMetaObject creation time in the database as local time.
 | 
			
		||||
func (m *LFSMetaObject) AfterLoad() {
 | 
			
		||||
	m.Created = time.Unix(m.CreatedUnix, 0).Local()
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,6 @@ import (
 | 
			
		||||
	"net/smtp"
 | 
			
		||||
	"net/textproto"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/Unknwon/com"
 | 
			
		||||
	"github.com/go-macaron/binding"
 | 
			
		||||
@@ -23,6 +22,7 @@ import (
 | 
			
		||||
	"code.gitea.io/gitea/modules/auth/oauth2"
 | 
			
		||||
	"code.gitea.io/gitea/modules/auth/pam"
 | 
			
		||||
	"code.gitea.io/gitea/modules/log"
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// LoginType represents an login type.
 | 
			
		||||
@@ -147,10 +147,8 @@ type LoginSource struct {
 | 
			
		||||
	IsSyncEnabled bool            `xorm:"INDEX NOT NULL DEFAULT false"`
 | 
			
		||||
	Cfg           core.Conversion `xorm:"TEXT"`
 | 
			
		||||
 | 
			
		||||
	Created     time.Time `xorm:"-"`
 | 
			
		||||
	CreatedUnix int64     `xorm:"INDEX created"`
 | 
			
		||||
	Updated     time.Time `xorm:"-"`
 | 
			
		||||
	UpdatedUnix int64     `xorm:"INDEX updated"`
 | 
			
		||||
	CreatedUnix util.TimeStamp `xorm:"INDEX created"`
 | 
			
		||||
	UpdatedUnix util.TimeStamp `xorm:"INDEX updated"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Cell2Int64 converts a xorm.Cell type to int64,
 | 
			
		||||
@@ -183,12 +181,6 @@ func (source *LoginSource) BeforeSet(colName string, val xorm.Cell) {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AfterLoad is invoked from XORM after setting the values of all fields of this object.
 | 
			
		||||
func (source *LoginSource) AfterLoad() {
 | 
			
		||||
	source.Created = time.Unix(source.CreatedUnix, 0).Local()
 | 
			
		||||
	source.Updated = time.Unix(source.UpdatedUnix, 0).Local()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TypeName return name of this login source type.
 | 
			
		||||
func (source *LoginSource) TypeName() string {
 | 
			
		||||
	return LoginNames[source.Type]
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,8 @@ package models
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type (
 | 
			
		||||
@@ -51,32 +52,8 @@ type Notification struct {
 | 
			
		||||
	Issue      *Issue      `xorm:"-"`
 | 
			
		||||
	Repository *Repository `xorm:"-"`
 | 
			
		||||
 | 
			
		||||
	Created     time.Time `xorm:"-"`
 | 
			
		||||
	CreatedUnix int64     `xorm:"INDEX NOT NULL"`
 | 
			
		||||
	Updated     time.Time `xorm:"-"`
 | 
			
		||||
	UpdatedUnix int64     `xorm:"INDEX NOT NULL"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BeforeInsert runs while inserting a record
 | 
			
		||||
func (n *Notification) BeforeInsert() {
 | 
			
		||||
	var (
 | 
			
		||||
		now     = time.Now()
 | 
			
		||||
		nowUnix = now.Unix()
 | 
			
		||||
	)
 | 
			
		||||
	n.Created = now
 | 
			
		||||
	n.CreatedUnix = nowUnix
 | 
			
		||||
	n.Updated = now
 | 
			
		||||
	n.UpdatedUnix = nowUnix
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BeforeUpdate runs while updating a record
 | 
			
		||||
func (n *Notification) BeforeUpdate() {
 | 
			
		||||
	var (
 | 
			
		||||
		now     = time.Now()
 | 
			
		||||
		nowUnix = now.Unix()
 | 
			
		||||
	)
 | 
			
		||||
	n.Updated = now
 | 
			
		||||
	n.UpdatedUnix = nowUnix
 | 
			
		||||
	CreatedUnix util.TimeStamp `xorm:"created INDEX NOT NULL"`
 | 
			
		||||
	UpdatedUnix util.TimeStamp `xorm:"updated INDEX NOT NULL"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CreateOrUpdateIssueNotifications creates an issue notification
 | 
			
		||||
@@ -212,6 +189,7 @@ func getIssueNotification(e Engine, userID, issueID int64) (*Notification, error
 | 
			
		||||
func NotificationsForUser(user *User, statuses []NotificationStatus, page, perPage int) ([]*Notification, error) {
 | 
			
		||||
	return notificationsForUser(x, user, statuses, page, perPage)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func notificationsForUser(e Engine, user *User, statuses []NotificationStatus, page, perPage int) (notifications []*Notification, err error) {
 | 
			
		||||
	if len(statuses) == 0 {
 | 
			
		||||
		return
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,7 @@ import (
 | 
			
		||||
	"code.gitea.io/gitea/modules/process"
 | 
			
		||||
	"code.gitea.io/gitea/modules/setting"
 | 
			
		||||
	"code.gitea.io/gitea/modules/sync"
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
	api "code.gitea.io/sdk/gitea"
 | 
			
		||||
 | 
			
		||||
	"github.com/Unknwon/com"
 | 
			
		||||
@@ -71,23 +72,7 @@ type PullRequest struct {
 | 
			
		||||
	MergedCommitID string         `xorm:"VARCHAR(40)"`
 | 
			
		||||
	MergerID       int64          `xorm:"INDEX"`
 | 
			
		||||
	Merger         *User          `xorm:"-"`
 | 
			
		||||
	Merged         time.Time `xorm:"-"`
 | 
			
		||||
	MergedUnix     int64     `xorm:"INDEX"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BeforeUpdate is invoked from XORM before updating an object of this type.
 | 
			
		||||
func (pr *PullRequest) BeforeUpdate() {
 | 
			
		||||
	pr.MergedUnix = pr.Merged.Unix()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AfterLoad is invoked from XORM after setting the values of all fields of this object.
 | 
			
		||||
// Note: don't try to get Issue because will end up recursive querying.
 | 
			
		||||
func (pr *PullRequest) AfterLoad() {
 | 
			
		||||
	if !pr.HasMerged {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pr.Merged = time.Unix(pr.MergedUnix, 0).Local()
 | 
			
		||||
	MergedUnix     util.TimeStamp `xorm:"updated INDEX"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Note: don't try to get Issue because will end up recursive querying.
 | 
			
		||||
@@ -194,8 +179,8 @@ func (pr *PullRequest) APIFormat() *api.PullRequest {
 | 
			
		||||
		Base:      apiBaseBranchInfo,
 | 
			
		||||
		Head:      apiHeadBranchInfo,
 | 
			
		||||
		MergeBase: pr.MergeBase,
 | 
			
		||||
		Created:   &pr.Issue.Created,
 | 
			
		||||
		Updated:   &pr.Issue.Updated,
 | 
			
		||||
		Created:   pr.Issue.CreatedUnix.AsTimePtr(),
 | 
			
		||||
		Updated:   pr.Issue.UpdatedUnix.AsTimePtr(),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if pr.Status != PullRequestStatusChecking {
 | 
			
		||||
@@ -203,7 +188,7 @@ func (pr *PullRequest) APIFormat() *api.PullRequest {
 | 
			
		||||
		apiPullRequest.Mergeable = mergeable
 | 
			
		||||
	}
 | 
			
		||||
	if pr.HasMerged {
 | 
			
		||||
		apiPullRequest.Merged = &pr.Merged
 | 
			
		||||
		apiPullRequest.Merged = pr.MergedUnix.AsTimePtr()
 | 
			
		||||
		apiPullRequest.MergedCommitID = &pr.MergedCommitID
 | 
			
		||||
		apiPullRequest.MergedBy = pr.Merger.APIFormat()
 | 
			
		||||
	}
 | 
			
		||||
@@ -330,7 +315,7 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository) (err error
 | 
			
		||||
		return fmt.Errorf("GetBranchCommit: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pr.Merged = time.Now()
 | 
			
		||||
	pr.MergedUnix = util.TimeStampNow()
 | 
			
		||||
	pr.Merger = doer
 | 
			
		||||
	pr.MergerID = doer.ID
 | 
			
		||||
 | 
			
		||||
@@ -396,7 +381,7 @@ func (pr *PullRequest) setMerged() (err error) {
 | 
			
		||||
	if pr.HasMerged {
 | 
			
		||||
		return fmt.Errorf("PullRequest[%d] already merged", pr.Index)
 | 
			
		||||
	}
 | 
			
		||||
	if pr.MergedCommitID == "" || pr.Merged.IsZero() || pr.Merger == nil {
 | 
			
		||||
	if pr.MergedCommitID == "" || pr.MergedUnix == 0 || pr.Merger == nil {
 | 
			
		||||
		return fmt.Errorf("Unable to merge PullRequest[%d], some required fields are empty", pr.Index)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -442,7 +427,7 @@ func (pr *PullRequest) manuallyMerged() bool {
 | 
			
		||||
	}
 | 
			
		||||
	if commit != nil {
 | 
			
		||||
		pr.MergedCommitID = commit.ID.String()
 | 
			
		||||
		pr.Merged = commit.Author.When
 | 
			
		||||
		pr.MergedUnix = util.TimeStamp(commit.Author.When.Unix())
 | 
			
		||||
		pr.Status = PullRequestStatusManuallyMerged
 | 
			
		||||
		merger, _ := GetUserByEmail(commit.Author.Email)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -8,11 +8,11 @@ import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/git"
 | 
			
		||||
	"code.gitea.io/gitea/modules/process"
 | 
			
		||||
	"code.gitea.io/gitea/modules/setting"
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
	api "code.gitea.io/sdk/gitea"
 | 
			
		||||
	"github.com/go-xorm/builder"
 | 
			
		||||
)
 | 
			
		||||
@@ -35,23 +35,8 @@ type Release struct {
 | 
			
		||||
	IsDraft          bool           `xorm:"NOT NULL DEFAULT false"`
 | 
			
		||||
	IsPrerelease     bool           `xorm:"NOT NULL DEFAULT false"`
 | 
			
		||||
	IsTag            bool           `xorm:"NOT NULL DEFAULT false"`
 | 
			
		||||
 | 
			
		||||
	Attachments      []*Attachment  `xorm:"-"`
 | 
			
		||||
 | 
			
		||||
	Created     time.Time `xorm:"-"`
 | 
			
		||||
	CreatedUnix int64     `xorm:"INDEX"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BeforeInsert is invoked from XORM before inserting an object of this type.
 | 
			
		||||
func (r *Release) BeforeInsert() {
 | 
			
		||||
	if r.CreatedUnix == 0 {
 | 
			
		||||
		r.CreatedUnix = time.Now().Unix()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AfterLoad is invoked from XORM after setting the values of all fields of this object.
 | 
			
		||||
func (r *Release) AfterLoad() {
 | 
			
		||||
	r.Created = time.Unix(r.CreatedUnix, 0).Local()
 | 
			
		||||
	CreatedUnix      util.TimeStamp `xorm:"created INDEX"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r *Release) loadAttributes(e Engine) error {
 | 
			
		||||
@@ -104,8 +89,8 @@ func (r *Release) APIFormat() *api.Release {
 | 
			
		||||
		ZipURL:       r.ZipURL(),
 | 
			
		||||
		IsDraft:      r.IsDraft,
 | 
			
		||||
		IsPrerelease: r.IsPrerelease,
 | 
			
		||||
		CreatedAt:    r.Created,
 | 
			
		||||
		PublishedAt:  r.Created,
 | 
			
		||||
		CreatedAt:    r.CreatedUnix.AsTime(),
 | 
			
		||||
		PublishedAt:  r.CreatedUnix.AsTime(),
 | 
			
		||||
		Publisher:    r.Publisher.APIFormat(),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -144,7 +129,7 @@ func createTag(gitRepo *git.Repository, rel *Release) error {
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		rel.Sha1 = commit.ID.String()
 | 
			
		||||
		rel.CreatedUnix = commit.Author.When.Unix()
 | 
			
		||||
		rel.CreatedUnix = util.TimeStamp(commit.Author.When.Unix())
 | 
			
		||||
		rel.NumCommits, err = commit.CommitsCount()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return fmt.Errorf("CommitsCount: %v", err)
 | 
			
		||||
@@ -345,7 +330,7 @@ func (rs *releaseSorter) Less(i, j int) bool {
 | 
			
		||||
	if diffNum != 0 {
 | 
			
		||||
		return diffNum > 0
 | 
			
		||||
	}
 | 
			
		||||
	return rs.rels[i].Created.After(rs.rels[j].Created)
 | 
			
		||||
	return rs.rels[i].CreatedUnix > rs.rels[j].CreatedUnix
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (rs *releaseSorter) Swap(i, j int) {
 | 
			
		||||
 
 | 
			
		||||
@@ -27,6 +27,7 @@ import (
 | 
			
		||||
	"code.gitea.io/gitea/modules/process"
 | 
			
		||||
	"code.gitea.io/gitea/modules/setting"
 | 
			
		||||
	"code.gitea.io/gitea/modules/sync"
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
	api "code.gitea.io/sdk/gitea"
 | 
			
		||||
 | 
			
		||||
	"github.com/Unknwon/cae/zip"
 | 
			
		||||
@@ -211,10 +212,8 @@ type Repository struct {
 | 
			
		||||
	Size          int64              `xorm:"NOT NULL DEFAULT 0"`
 | 
			
		||||
	IndexerStatus *RepoIndexerStatus `xorm:"-"`
 | 
			
		||||
 | 
			
		||||
	Created     time.Time `xorm:"-"`
 | 
			
		||||
	CreatedUnix int64     `xorm:"INDEX created"`
 | 
			
		||||
	Updated     time.Time `xorm:"-"`
 | 
			
		||||
	UpdatedUnix int64     `xorm:"INDEX updated"`
 | 
			
		||||
	CreatedUnix util.TimeStamp `xorm:"INDEX created"`
 | 
			
		||||
	UpdatedUnix util.TimeStamp `xorm:"INDEX updated"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AfterLoad is invoked from XORM after setting the values of all fields of this object.
 | 
			
		||||
@@ -227,8 +226,6 @@ func (repo *Repository) AfterLoad() {
 | 
			
		||||
	repo.NumOpenIssues = repo.NumIssues - repo.NumClosedIssues
 | 
			
		||||
	repo.NumOpenPulls = repo.NumPulls - repo.NumClosedPulls
 | 
			
		||||
	repo.NumOpenMilestones = repo.NumMilestones - repo.NumClosedMilestones
 | 
			
		||||
	repo.Created = time.Unix(repo.CreatedUnix, 0).Local()
 | 
			
		||||
	repo.Updated = time.Unix(repo.UpdatedUnix, 0)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MustOwner always returns a valid *User object to avoid
 | 
			
		||||
@@ -309,8 +306,8 @@ func (repo *Repository) innerAPIFormat(mode AccessMode, isParent bool) *api.Repo
 | 
			
		||||
		Watchers:      repo.NumWatches,
 | 
			
		||||
		OpenIssues:    repo.NumOpenIssues,
 | 
			
		||||
		DefaultBranch: repo.DefaultBranch,
 | 
			
		||||
		Created:       repo.Created,
 | 
			
		||||
		Updated:       repo.Updated,
 | 
			
		||||
		Created:       repo.CreatedUnix.AsTime(),
 | 
			
		||||
		Updated:       repo.UpdatedUnix.AsTime(),
 | 
			
		||||
		Permissions:   permission,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1014,7 +1011,7 @@ func MigrateRepository(doer, u *User, opts MigrateRepoOptions) (*Repository, err
 | 
			
		||||
			RepoID:         repo.ID,
 | 
			
		||||
			Interval:       setting.Mirror.DefaultInterval,
 | 
			
		||||
			EnablePrune:    true,
 | 
			
		||||
			NextUpdate:  time.Now().Add(setting.Mirror.DefaultInterval),
 | 
			
		||||
			NextUpdateUnix: util.TimeStampNow().AddDuration(setting.Mirror.DefaultInterval),
 | 
			
		||||
		}); err != nil {
 | 
			
		||||
			return repo, fmt.Errorf("InsertOne: %v", err)
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -31,10 +31,8 @@ type Mirror struct {
 | 
			
		||||
	Interval    time.Duration
 | 
			
		||||
	EnablePrune bool `xorm:"NOT NULL DEFAULT true"`
 | 
			
		||||
 | 
			
		||||
	Updated        time.Time `xorm:"-"`
 | 
			
		||||
	UpdatedUnix    int64     `xorm:"INDEX"`
 | 
			
		||||
	NextUpdate     time.Time `xorm:"-"`
 | 
			
		||||
	NextUpdateUnix int64     `xorm:"INDEX"`
 | 
			
		||||
	UpdatedUnix    util.TimeStamp `xorm:"INDEX"`
 | 
			
		||||
	NextUpdateUnix util.TimeStamp `xorm:"INDEX"`
 | 
			
		||||
 | 
			
		||||
	address string `xorm:"-"`
 | 
			
		||||
}
 | 
			
		||||
@@ -42,16 +40,8 @@ type Mirror struct {
 | 
			
		||||
// BeforeInsert will be invoked by XORM before inserting a record
 | 
			
		||||
func (m *Mirror) BeforeInsert() {
 | 
			
		||||
	if m != nil {
 | 
			
		||||
		m.UpdatedUnix = time.Now().Unix()
 | 
			
		||||
		m.NextUpdateUnix = m.NextUpdate.Unix()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BeforeUpdate is invoked from XORM before updating this object.
 | 
			
		||||
func (m *Mirror) BeforeUpdate() {
 | 
			
		||||
	if m != nil {
 | 
			
		||||
		m.UpdatedUnix = m.Updated.Unix()
 | 
			
		||||
		m.NextUpdateUnix = m.NextUpdate.Unix()
 | 
			
		||||
		m.UpdatedUnix = util.TimeStampNow()
 | 
			
		||||
		m.NextUpdateUnix = util.TimeStampNow()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -66,14 +56,11 @@ func (m *Mirror) AfterLoad(session *xorm.Session) {
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Error(3, "getRepositoryByID[%d]: %v", m.ID, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m.Updated = time.Unix(m.UpdatedUnix, 0).Local()
 | 
			
		||||
	m.NextUpdate = time.Unix(m.NextUpdateUnix, 0).Local()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ScheduleNextUpdate calculates and sets next update time.
 | 
			
		||||
func (m *Mirror) ScheduleNextUpdate() {
 | 
			
		||||
	m.NextUpdate = time.Now().Add(m.Interval)
 | 
			
		||||
	m.NextUpdateUnix = util.TimeStampNow().AddDuration(m.Interval)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func remoteAddress(repoPath string) (string, error) {
 | 
			
		||||
@@ -193,7 +180,7 @@ func (m *Mirror) runSync() bool {
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m.Updated = time.Now()
 | 
			
		||||
	m.UpdatedUnix = util.TimeStampNow()
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,8 @@ package models
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
 | 
			
		||||
	"github.com/Unknwon/com"
 | 
			
		||||
	"github.com/go-xorm/core"
 | 
			
		||||
@@ -19,8 +20,7 @@ type RepoUnit struct {
 | 
			
		||||
	RepoID      int64           `xorm:"INDEX(s)"`
 | 
			
		||||
	Type        UnitType        `xorm:"INDEX(s)"`
 | 
			
		||||
	Config      core.Conversion `xorm:"TEXT"`
 | 
			
		||||
	CreatedUnix int64           `xorm:"INDEX CREATED"`
 | 
			
		||||
	Created     time.Time       `xorm:"-"`
 | 
			
		||||
	CreatedUnix util.TimeStamp  `xorm:"INDEX CREATED"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UnitConfig describes common unit config
 | 
			
		||||
@@ -105,11 +105,6 @@ func (r *RepoUnit) BeforeSet(colName string, val xorm.Cell) {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AfterLoad is invoked from XORM after setting the values of all fields of this object.
 | 
			
		||||
func (r *RepoUnit) AfterLoad() {
 | 
			
		||||
	r.Created = time.Unix(r.CreatedUnix, 0).Local()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Unit returns Unit
 | 
			
		||||
func (r *RepoUnit) Unit() Unit {
 | 
			
		||||
	return Units[r.Type]
 | 
			
		||||
 
 | 
			
		||||
@@ -25,6 +25,7 @@ import (
 | 
			
		||||
	"code.gitea.io/gitea/modules/log"
 | 
			
		||||
	"code.gitea.io/gitea/modules/process"
 | 
			
		||||
	"code.gitea.io/gitea/modules/setting"
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
@@ -54,20 +55,16 @@ type PublicKey struct {
 | 
			
		||||
	Mode        AccessMode `xorm:"NOT NULL DEFAULT 2"`
 | 
			
		||||
	Type        KeyType    `xorm:"NOT NULL DEFAULT 1"`
 | 
			
		||||
 | 
			
		||||
	Created           time.Time `xorm:"-"`
 | 
			
		||||
	CreatedUnix       int64     `xorm:"created"`
 | 
			
		||||
	Updated           time.Time `xorm:"-"`
 | 
			
		||||
	UpdatedUnix       int64     `xorm:"updated"`
 | 
			
		||||
	CreatedUnix       util.TimeStamp `xorm:"created"`
 | 
			
		||||
	UpdatedUnix       util.TimeStamp `xorm:"updated"`
 | 
			
		||||
	HasRecentActivity bool           `xorm:"-"`
 | 
			
		||||
	HasUsed           bool           `xorm:"-"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AfterLoad is invoked from XORM after setting the values of all fields of this object.
 | 
			
		||||
func (key *PublicKey) AfterLoad() {
 | 
			
		||||
	key.Created = time.Unix(key.CreatedUnix, 0).Local()
 | 
			
		||||
	key.Updated = time.Unix(key.UpdatedUnix, 0).Local()
 | 
			
		||||
	key.HasUsed = key.Updated.After(key.Created)
 | 
			
		||||
	key.HasRecentActivity = key.Updated.Add(7 * 24 * time.Hour).After(time.Now())
 | 
			
		||||
	key.HasUsed = key.UpdatedUnix > key.CreatedUnix
 | 
			
		||||
	key.HasRecentActivity = key.UpdatedUnix.AddDuration(7*24*time.Hour) > util.TimeStampNow()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// OmitEmail returns content of public key without email address.
 | 
			
		||||
@@ -484,7 +481,7 @@ func UpdatePublicKeyUpdated(id int64) error {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_, err := x.ID(id).Cols("updated_unix").Update(&PublicKey{
 | 
			
		||||
		UpdatedUnix: time.Now().Unix(),
 | 
			
		||||
		UpdatedUnix: util.TimeStampNow(),
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
 
 | 
			
		||||
@@ -8,11 +8,11 @@ import (
 | 
			
		||||
	"container/list"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/git"
 | 
			
		||||
	"code.gitea.io/gitea/modules/log"
 | 
			
		||||
	"code.gitea.io/gitea/modules/setting"
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
	api "code.gitea.io/sdk/gitea"
 | 
			
		||||
 | 
			
		||||
	"github.com/go-xorm/xorm"
 | 
			
		||||
@@ -65,17 +65,8 @@ type CommitStatus struct {
 | 
			
		||||
	Creator     *User             `xorm:"-"`
 | 
			
		||||
	CreatorID   int64
 | 
			
		||||
 | 
			
		||||
	Created     time.Time `xorm:"-"`
 | 
			
		||||
	CreatedUnix int64     `xorm:"INDEX created"`
 | 
			
		||||
	Updated     time.Time `xorm:"-"`
 | 
			
		||||
	UpdatedUnix int64     `xorm:"INDEX updated"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AfterLoad is invoked from XORM after setting the value of a field of
 | 
			
		||||
// this object.
 | 
			
		||||
func (status *CommitStatus) AfterLoad() {
 | 
			
		||||
	status.Created = time.Unix(status.CreatedUnix, 0).Local()
 | 
			
		||||
	status.Updated = time.Unix(status.UpdatedUnix, 0).Local()
 | 
			
		||||
	CreatedUnix util.TimeStamp `xorm:"INDEX created"`
 | 
			
		||||
	UpdatedUnix util.TimeStamp `xorm:"INDEX updated"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (status *CommitStatus) loadRepo(e Engine) (err error) {
 | 
			
		||||
@@ -106,8 +97,8 @@ func (status *CommitStatus) APIURL() string {
 | 
			
		||||
func (status *CommitStatus) APIFormat() *api.Status {
 | 
			
		||||
	status.loadRepo(x)
 | 
			
		||||
	apiStatus := &api.Status{
 | 
			
		||||
		Created:     status.Created,
 | 
			
		||||
		Updated:     status.Created,
 | 
			
		||||
		Created:     status.CreatedUnix.AsTime(),
 | 
			
		||||
		Updated:     status.CreatedUnix.AsTime(),
 | 
			
		||||
		State:       api.StatusState(status.State),
 | 
			
		||||
		TargetURL:   status.TargetURL,
 | 
			
		||||
		Description: status.Description,
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +10,7 @@ import (
 | 
			
		||||
	gouuid "github.com/satori/go.uuid"
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/gitea/modules/base"
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// AccessToken represents a personal access token.
 | 
			
		||||
@@ -19,20 +20,16 @@ type AccessToken struct {
 | 
			
		||||
	Name string
 | 
			
		||||
	Sha1 string `xorm:"UNIQUE VARCHAR(40)"`
 | 
			
		||||
 | 
			
		||||
	Created           time.Time `xorm:"-"`
 | 
			
		||||
	CreatedUnix       int64     `xorm:"INDEX created"`
 | 
			
		||||
	Updated           time.Time `xorm:"-"`
 | 
			
		||||
	UpdatedUnix       int64     `xorm:"INDEX updated"`
 | 
			
		||||
	CreatedUnix       util.TimeStamp `xorm:"INDEX created"`
 | 
			
		||||
	UpdatedUnix       util.TimeStamp `xorm:"INDEX updated"`
 | 
			
		||||
	HasRecentActivity bool           `xorm:"-"`
 | 
			
		||||
	HasUsed           bool           `xorm:"-"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AfterLoad is invoked from XORM after setting the values of all fields of this object.
 | 
			
		||||
func (t *AccessToken) AfterLoad() {
 | 
			
		||||
	t.Created = time.Unix(t.CreatedUnix, 0).Local()
 | 
			
		||||
	t.Updated = time.Unix(t.UpdatedUnix, 0).Local()
 | 
			
		||||
	t.HasUsed = t.Updated.After(t.Created)
 | 
			
		||||
	t.HasRecentActivity = t.Updated.Add(7 * 24 * time.Hour).After(time.Now())
 | 
			
		||||
	t.HasUsed = t.UpdatedUnix > t.CreatedUnix
 | 
			
		||||
	t.HasRecentActivity = t.UpdatedUnix.AddDuration(7*24*time.Hour) > util.TimeStampNow()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewAccessToken creates new access token.
 | 
			
		||||
 
 | 
			
		||||
@@ -8,13 +8,13 @@ import (
 | 
			
		||||
	"crypto/md5"
 | 
			
		||||
	"crypto/subtle"
 | 
			
		||||
	"encoding/base64"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/Unknwon/com"
 | 
			
		||||
	"github.com/pquerna/otp/totp"
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/gitea/modules/base"
 | 
			
		||||
	"code.gitea.io/gitea/modules/setting"
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// TwoFactor represents a two-factor authentication token.
 | 
			
		||||
@@ -23,17 +23,8 @@ type TwoFactor struct {
 | 
			
		||||
	UID          int64 `xorm:"UNIQUE"`
 | 
			
		||||
	Secret       string
 | 
			
		||||
	ScratchToken string
 | 
			
		||||
 | 
			
		||||
	Created     time.Time `xorm:"-"`
 | 
			
		||||
	CreatedUnix int64     `xorm:"INDEX created"`
 | 
			
		||||
	Updated     time.Time `xorm:"-"`
 | 
			
		||||
	UpdatedUnix int64     `xorm:"INDEX updated"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AfterLoad is invoked from XORM after setting the values of all fields of this object.
 | 
			
		||||
func (t *TwoFactor) AfterLoad() {
 | 
			
		||||
	t.Created = time.Unix(t.CreatedUnix, 0).Local()
 | 
			
		||||
	t.Updated = time.Unix(t.UpdatedUnix, 0).Local()
 | 
			
		||||
	CreatedUnix  util.TimeStamp `xorm:"INDEX created"`
 | 
			
		||||
	UpdatedUnix  util.TimeStamp `xorm:"INDEX updated"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GenerateScratchToken recreates the scratch token the user is using.
 | 
			
		||||
 
 | 
			
		||||
@@ -14,6 +14,7 @@ import (
 | 
			
		||||
	"code.gitea.io/git"
 | 
			
		||||
	"code.gitea.io/gitea/modules/cache"
 | 
			
		||||
	"code.gitea.io/gitea/modules/log"
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// env keys for git hooks need
 | 
			
		||||
@@ -158,8 +159,7 @@ func pushUpdateAddTag(repo *Repository, gitRepo *git.Repository, tagName string)
 | 
			
		||||
			IsDraft:      false,
 | 
			
		||||
			IsPrerelease: false,
 | 
			
		||||
			IsTag:        true,
 | 
			
		||||
			Created:      createdAt,
 | 
			
		||||
			CreatedUnix:  createdAt.Unix(),
 | 
			
		||||
			CreatedUnix:  util.TimeStamp(createdAt.Unix()),
 | 
			
		||||
		}
 | 
			
		||||
		if author != nil {
 | 
			
		||||
			rel.PublisherID = author.ID
 | 
			
		||||
@@ -170,8 +170,7 @@ func pushUpdateAddTag(repo *Repository, gitRepo *git.Repository, tagName string)
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		rel.Sha1 = commit.ID.String()
 | 
			
		||||
		rel.Created = createdAt
 | 
			
		||||
		rel.CreatedUnix = createdAt.Unix()
 | 
			
		||||
		rel.CreatedUnix = util.TimeStamp(createdAt.Unix())
 | 
			
		||||
		rel.NumCommits = commitsCount
 | 
			
		||||
		rel.IsDraft = false
 | 
			
		||||
		if rel.IsTag && author != nil {
 | 
			
		||||
 
 | 
			
		||||
@@ -94,12 +94,9 @@ type User struct {
 | 
			
		||||
	Rands            string `xorm:"VARCHAR(10)"`
 | 
			
		||||
	Salt             string `xorm:"VARCHAR(10)"`
 | 
			
		||||
 | 
			
		||||
	Created       time.Time `xorm:"-"`
 | 
			
		||||
	CreatedUnix   int64     `xorm:"INDEX created"`
 | 
			
		||||
	Updated       time.Time `xorm:"-"`
 | 
			
		||||
	UpdatedUnix   int64     `xorm:"INDEX updated"`
 | 
			
		||||
	LastLogin     time.Time `xorm:"-"`
 | 
			
		||||
	LastLoginUnix int64     `xorm:"INDEX"`
 | 
			
		||||
	CreatedUnix   util.TimeStamp `xorm:"INDEX created"`
 | 
			
		||||
	UpdatedUnix   util.TimeStamp `xorm:"INDEX updated"`
 | 
			
		||||
	LastLoginUnix util.TimeStamp `xorm:"INDEX"`
 | 
			
		||||
 | 
			
		||||
	// Remember visibility choice for convenience, true for private
 | 
			
		||||
	LastRepoVisibility bool
 | 
			
		||||
@@ -145,7 +142,7 @@ func (u *User) BeforeUpdate() {
 | 
			
		||||
 | 
			
		||||
// SetLastLogin set time to last login
 | 
			
		||||
func (u *User) SetLastLogin() {
 | 
			
		||||
	u.LastLoginUnix = time.Now().Unix()
 | 
			
		||||
	u.LastLoginUnix = util.TimeStampNow()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UpdateDiffViewStyle updates the users diff view style
 | 
			
		||||
@@ -154,12 +151,13 @@ func (u *User) UpdateDiffViewStyle(style string) error {
 | 
			
		||||
	return UpdateUserCols(u, "diff_view_style")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
// AfterLoad is invoked from XORM after setting the values of all fields of this object.
 | 
			
		||||
func (u *User) AfterLoad() {
 | 
			
		||||
	u.Created = time.Unix(u.CreatedUnix, 0).Local()
 | 
			
		||||
	u.Updated = time.Unix(u.UpdatedUnix, 0).Local()
 | 
			
		||||
	u.LastLogin = time.Unix(u.LastLoginUnix, 0).Local()
 | 
			
		||||
}
 | 
			
		||||
}*/
 | 
			
		||||
 | 
			
		||||
// getEmail returns an noreply email, if the user has set to keep his
 | 
			
		||||
// email address private, otherwise the primary email address.
 | 
			
		||||
 
 | 
			
		||||
@@ -17,6 +17,7 @@ import (
 | 
			
		||||
	"code.gitea.io/gitea/modules/log"
 | 
			
		||||
	"code.gitea.io/gitea/modules/setting"
 | 
			
		||||
	"code.gitea.io/gitea/modules/sync"
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
	api "code.gitea.io/sdk/gitea"
 | 
			
		||||
 | 
			
		||||
	gouuid "github.com/satori/go.uuid"
 | 
			
		||||
@@ -105,10 +106,8 @@ type Webhook struct {
 | 
			
		||||
	Meta         string     `xorm:"TEXT"` // store hook-specific attributes
 | 
			
		||||
	LastStatus   HookStatus // Last delivery status
 | 
			
		||||
 | 
			
		||||
	Created     time.Time `xorm:"-"`
 | 
			
		||||
	CreatedUnix int64     `xorm:"INDEX created"`
 | 
			
		||||
	Updated     time.Time `xorm:"-"`
 | 
			
		||||
	UpdatedUnix int64     `xorm:"INDEX updated"`
 | 
			
		||||
	CreatedUnix util.TimeStamp `xorm:"INDEX created"`
 | 
			
		||||
	UpdatedUnix util.TimeStamp `xorm:"INDEX updated"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AfterLoad updates the webhook object upon setting a column
 | 
			
		||||
@@ -117,9 +116,6 @@ func (w *Webhook) AfterLoad() {
 | 
			
		||||
	if err := json.Unmarshal([]byte(w.Events), w.HookEvent); err != nil {
 | 
			
		||||
		log.Error(3, "Unmarshal[%d]: %v", w.ID, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	w.Created = time.Unix(w.CreatedUnix, 0).Local()
 | 
			
		||||
	w.Updated = time.Unix(w.UpdatedUnix, 0).Local()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetSlackHook returns slack metadata
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,6 @@ package auth
 | 
			
		||||
import (
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/Unknwon/com"
 | 
			
		||||
	"github.com/go-macaron/binding"
 | 
			
		||||
@@ -19,6 +18,7 @@ import (
 | 
			
		||||
	"code.gitea.io/gitea/modules/base"
 | 
			
		||||
	"code.gitea.io/gitea/modules/log"
 | 
			
		||||
	"code.gitea.io/gitea/modules/setting"
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
	"code.gitea.io/gitea/modules/validation"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -59,7 +59,7 @@ func SignedInID(ctx *macaron.Context, sess session.Store) int64 {
 | 
			
		||||
				}
 | 
			
		||||
				return 0
 | 
			
		||||
			}
 | 
			
		||||
			t.Updated = time.Now()
 | 
			
		||||
			t.UpdatedUnix = util.TimeStampNow()
 | 
			
		||||
			if err = models.UpdateAccessToken(t); err != nil {
 | 
			
		||||
				log.Error(4, "UpdateAccessToken: %v", err)
 | 
			
		||||
			}
 | 
			
		||||
 
 | 
			
		||||
@@ -26,6 +26,7 @@ import (
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/gitea/modules/log"
 | 
			
		||||
	"code.gitea.io/gitea/modules/setting"
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
	"github.com/Unknwon/com"
 | 
			
		||||
	"github.com/Unknwon/i18n"
 | 
			
		||||
	"github.com/gogits/chardet"
 | 
			
		||||
@@ -357,11 +358,15 @@ func timeSincePro(then, now time.Time, lang string) string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func timeSince(then, now time.Time, lang string) string {
 | 
			
		||||
	return timeSinceUnix(then.Unix(), now.Unix(), lang)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func timeSinceUnix(then, now int64, lang string) string {
 | 
			
		||||
	lbl := "tool.ago"
 | 
			
		||||
	diff := now.Unix() - then.Unix()
 | 
			
		||||
	if then.After(now) {
 | 
			
		||||
	diff := now - then
 | 
			
		||||
	if then > now {
 | 
			
		||||
		lbl = "tool.from_now"
 | 
			
		||||
		diff = then.Unix() - now.Unix()
 | 
			
		||||
		diff = then - now
 | 
			
		||||
	}
 | 
			
		||||
	if diff <= 0 {
 | 
			
		||||
		return i18n.Tr(lang, "tool.now")
 | 
			
		||||
@@ -387,6 +392,17 @@ func htmlTimeSince(then, now time.Time, lang string) template.HTML {
 | 
			
		||||
		timeSince(then, now, lang)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TimeSinceUnix calculates the time interval and generate user-friendly string.
 | 
			
		||||
func TimeSinceUnix(then util.TimeStamp, lang string) template.HTML {
 | 
			
		||||
	return htmlTimeSinceUnix(then, util.TimeStamp(time.Now().Unix()), lang)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func htmlTimeSinceUnix(then, now util.TimeStamp, lang string) template.HTML {
 | 
			
		||||
	return template.HTML(fmt.Sprintf(`<span class="time-since" title="%s">%s</span>`,
 | 
			
		||||
		then.Format(setting.TimeFormat),
 | 
			
		||||
		timeSinceUnix(int64(then), int64(now), lang)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Storage space size types
 | 
			
		||||
const (
 | 
			
		||||
	Byte  = 1
 | 
			
		||||
 
 | 
			
		||||
@@ -70,6 +70,7 @@ func NewFuncMap() []template.FuncMap {
 | 
			
		||||
		"SafeJS":        SafeJS,
 | 
			
		||||
		"Str2html":      Str2html,
 | 
			
		||||
		"TimeSince":     base.TimeSince,
 | 
			
		||||
		"TimeSinceUnix": base.TimeSinceUnix,
 | 
			
		||||
		"RawTimeSince":  base.RawTimeSince,
 | 
			
		||||
		"FileSize":      base.FileSize,
 | 
			
		||||
		"Subtract":      base.Subtract,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										57
									
								
								modules/util/time_stamp.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								modules/util/time_stamp.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,57 @@
 | 
			
		||||
// Copyright 2017 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 util
 | 
			
		||||
 | 
			
		||||
import "time"
 | 
			
		||||
 | 
			
		||||
// TimeStamp defines a timestamp
 | 
			
		||||
type TimeStamp int64
 | 
			
		||||
 | 
			
		||||
// TimeStampNow returns now int64
 | 
			
		||||
func TimeStampNow() TimeStamp {
 | 
			
		||||
	return TimeStamp(time.Now().Unix())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Add adds seconds and return sum
 | 
			
		||||
func (ts TimeStamp) Add(seconds int64) TimeStamp {
 | 
			
		||||
	return ts + TimeStamp(seconds)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AddDuration adds time.Duration and return sum
 | 
			
		||||
func (ts TimeStamp) AddDuration(interval time.Duration) TimeStamp {
 | 
			
		||||
	return ts + TimeStamp(interval/time.Second)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Year returns the time's year
 | 
			
		||||
func (ts TimeStamp) Year() int {
 | 
			
		||||
	return ts.AsTime().Year()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AsTime convert timestamp as time.Time in Local locale
 | 
			
		||||
func (ts TimeStamp) AsTime() (tm time.Time) {
 | 
			
		||||
	tm = time.Unix(int64(ts), 0).Local()
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AsTimePtr convert timestamp as *time.Time in Local locale
 | 
			
		||||
func (ts TimeStamp) AsTimePtr() *time.Time {
 | 
			
		||||
	tm := time.Unix(int64(ts), 0).Local()
 | 
			
		||||
	return &tm
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Format formats timestamp as
 | 
			
		||||
func (ts TimeStamp) Format(f string) string {
 | 
			
		||||
	return ts.AsTime().Format(f)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FormatLong formats as RFC1123Z
 | 
			
		||||
func (ts TimeStamp) FormatLong() string {
 | 
			
		||||
	return ts.Format(time.RFC1123Z)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FormatShort formats as short
 | 
			
		||||
func (ts TimeStamp) FormatShort() string {
 | 
			
		||||
	return ts.Format("Jan 02, 2006")
 | 
			
		||||
}
 | 
			
		||||
@@ -82,7 +82,7 @@ func ToPublicKey(apiLink string, key *models.PublicKey) *api.PublicKey {
 | 
			
		||||
		URL:         apiLink + com.ToStr(key.ID),
 | 
			
		||||
		Title:       key.Name,
 | 
			
		||||
		Fingerprint: key.Fingerprint,
 | 
			
		||||
		Created:     key.Created,
 | 
			
		||||
		Created:     key.CreatedUnix.AsTime(),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -95,8 +95,8 @@ func ToGPGKey(key *models.GPGKey) *api.GPGKey {
 | 
			
		||||
			PrimaryKeyID:      k.PrimaryKeyID,
 | 
			
		||||
			KeyID:             k.KeyID,
 | 
			
		||||
			PublicKey:         k.Content,
 | 
			
		||||
			Created:           k.Created,
 | 
			
		||||
			Expires:           k.Expired,
 | 
			
		||||
			Created:           k.CreatedUnix.AsTime(),
 | 
			
		||||
			Expires:           k.ExpiredUnix.AsTime(),
 | 
			
		||||
			CanSign:           k.CanSign,
 | 
			
		||||
			CanEncryptComms:   k.CanEncryptComms,
 | 
			
		||||
			CanEncryptStorage: k.CanEncryptStorage,
 | 
			
		||||
@@ -112,8 +112,8 @@ func ToGPGKey(key *models.GPGKey) *api.GPGKey {
 | 
			
		||||
		PrimaryKeyID:      key.PrimaryKeyID,
 | 
			
		||||
		KeyID:             key.KeyID,
 | 
			
		||||
		PublicKey:         key.Content,
 | 
			
		||||
		Created:           key.Created,
 | 
			
		||||
		Expires:           key.Expired,
 | 
			
		||||
		Created:           key.CreatedUnix.AsTime(),
 | 
			
		||||
		Expires:           key.ExpiredUnix.AsTime(),
 | 
			
		||||
		Emails:            emails,
 | 
			
		||||
		SubsKey:           subkeys,
 | 
			
		||||
		CanSign:           key.CanSign,
 | 
			
		||||
@@ -152,8 +152,8 @@ func ToHook(repoLink string, w *models.Webhook) *api.Hook {
 | 
			
		||||
		Active:  w.IsActive,
 | 
			
		||||
		Config:  config,
 | 
			
		||||
		Events:  w.EventsArray(),
 | 
			
		||||
		Updated: w.Updated,
 | 
			
		||||
		Created: w.Created,
 | 
			
		||||
		Updated: w.UpdatedUnix.AsTime(),
 | 
			
		||||
		Created: w.CreatedUnix.AsTime(),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,7 @@ import (
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/gitea/models"
 | 
			
		||||
	"code.gitea.io/gitea/modules/context"
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ListMilestones list all the milestones for a repository
 | 
			
		||||
@@ -121,7 +122,7 @@ func CreateMilestone(ctx *context.APIContext, form api.CreateMilestoneOption) {
 | 
			
		||||
		RepoID:       ctx.Repo.Repository.ID,
 | 
			
		||||
		Name:         form.Title,
 | 
			
		||||
		Content:      form.Description,
 | 
			
		||||
		Deadline: *form.Deadline,
 | 
			
		||||
		DeadlineUnix: util.TimeStamp(form.Deadline.Unix()),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := models.NewMilestone(milestone); err != nil {
 | 
			
		||||
@@ -175,7 +176,7 @@ func EditMilestone(ctx *context.APIContext, form api.EditMilestoneOption) {
 | 
			
		||||
		milestone.Content = *form.Description
 | 
			
		||||
	}
 | 
			
		||||
	if form.Deadline != nil && !form.Deadline.IsZero() {
 | 
			
		||||
		milestone.Deadline = *form.Deadline
 | 
			
		||||
		milestone.DeadlineUnix = util.TimeStamp(form.Deadline.Unix())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := models.UpdateMilestone(milestone); err != nil {
 | 
			
		||||
 
 | 
			
		||||
@@ -97,7 +97,7 @@ func IsWatching(ctx *context.APIContext) {
 | 
			
		||||
			Subscribed:    true,
 | 
			
		||||
			Ignored:       false,
 | 
			
		||||
			Reason:        nil,
 | 
			
		||||
			CreatedAt:     ctx.Repo.Repository.Created,
 | 
			
		||||
			CreatedAt:     ctx.Repo.Repository.CreatedUnix.AsTime(),
 | 
			
		||||
			URL:           subscriptionURL(ctx.Repo.Repository),
 | 
			
		||||
			RepositoryURL: repositoryURL(ctx.Repo.Repository),
 | 
			
		||||
		})
 | 
			
		||||
@@ -134,7 +134,7 @@ func Watch(ctx *context.APIContext) {
 | 
			
		||||
		Subscribed:    true,
 | 
			
		||||
		Ignored:       false,
 | 
			
		||||
		Reason:        nil,
 | 
			
		||||
		CreatedAt:     ctx.Repo.Repository.Created,
 | 
			
		||||
		CreatedAt:     ctx.Repo.Repository.CreatedUnix.AsTime(),
 | 
			
		||||
		URL:           subscriptionURL(ctx.Repo.Repository),
 | 
			
		||||
		RepositoryURL: repositoryURL(ctx.Repo.Repository),
 | 
			
		||||
	})
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,7 @@ import (
 | 
			
		||||
	"code.gitea.io/gitea/modules/context"
 | 
			
		||||
	"code.gitea.io/gitea/modules/log"
 | 
			
		||||
	"code.gitea.io/gitea/modules/setting"
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// HTTP implmentation git smart HTTP protocol
 | 
			
		||||
@@ -167,7 +168,7 @@ func HTTP(ctx *context.Context) {
 | 
			
		||||
					return
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				token.Updated = time.Now()
 | 
			
		||||
				token.UpdatedUnix = util.TimeStampNow()
 | 
			
		||||
				if err = models.UpdateAccessToken(token); err != nil {
 | 
			
		||||
					ctx.Handle(http.StatusInternalServerError, "UpdateAccessToken", err)
 | 
			
		||||
				}
 | 
			
		||||
 
 | 
			
		||||
@@ -1141,7 +1141,7 @@ func NewMilestonePost(ctx *context.Context, form auth.CreateMilestoneForm) {
 | 
			
		||||
		RepoID:       ctx.Repo.Repository.ID,
 | 
			
		||||
		Name:         form.Title,
 | 
			
		||||
		Content:      form.Content,
 | 
			
		||||
		Deadline: deadline,
 | 
			
		||||
		DeadlineUnix: util.TimeStamp(deadline.Unix()),
 | 
			
		||||
	}); err != nil {
 | 
			
		||||
		ctx.Handle(500, "NewMilestone", err)
 | 
			
		||||
		return
 | 
			
		||||
@@ -1210,7 +1210,7 @@ func EditMilestonePost(ctx *context.Context, form auth.CreateMilestoneForm) {
 | 
			
		||||
	}
 | 
			
		||||
	m.Name = form.Title
 | 
			
		||||
	m.Content = form.Content
 | 
			
		||||
	m.Deadline = deadline
 | 
			
		||||
	m.DeadlineUnix = util.TimeStamp(deadline.Unix())
 | 
			
		||||
	if err = models.UpdateMilestone(m); err != nil {
 | 
			
		||||
		ctx.Handle(500, "UpdateMilestone", err)
 | 
			
		||||
		return
 | 
			
		||||
@@ -1243,7 +1243,7 @@ func ChangeMilestonStatus(ctx *context.Context) {
 | 
			
		||||
		ctx.Redirect(ctx.Repo.RepoLink + "/milestones?state=open")
 | 
			
		||||
	case "close":
 | 
			
		||||
		if !m.IsClosed {
 | 
			
		||||
			m.ClosedDate = time.Now()
 | 
			
		||||
			m.ClosedDateUnix = util.TimeStampNow()
 | 
			
		||||
			if err = models.ChangeMilestoneStatus(m, true); err != nil {
 | 
			
		||||
				ctx.Handle(500, "ChangeMilestoneStatus", err)
 | 
			
		||||
				return
 | 
			
		||||
 
 | 
			
		||||
@@ -16,6 +16,7 @@ import (
 | 
			
		||||
	"code.gitea.io/gitea/modules/context"
 | 
			
		||||
	"code.gitea.io/gitea/modules/log"
 | 
			
		||||
	"code.gitea.io/gitea/modules/setting"
 | 
			
		||||
	"code.gitea.io/gitea/modules/util"
 | 
			
		||||
	"code.gitea.io/gitea/routers/utils"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -119,7 +120,7 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) {
 | 
			
		||||
		} else {
 | 
			
		||||
			ctx.Repo.Mirror.EnablePrune = form.EnablePrune
 | 
			
		||||
			ctx.Repo.Mirror.Interval = interval
 | 
			
		||||
			ctx.Repo.Mirror.NextUpdate = time.Now().Add(interval)
 | 
			
		||||
			ctx.Repo.Mirror.NextUpdateUnix = util.TimeStampNow().AddDuration(interval)
 | 
			
		||||
			if err := models.UpdateMirror(ctx.Repo.Mirror); err != nil {
 | 
			
		||||
				ctx.RenderWithErr(ctx.Tr("repo.mirror_interval_invalid"), tplSettingsOptions, &form)
 | 
			
		||||
				return
 | 
			
		||||
 
 | 
			
		||||
@@ -29,8 +29,8 @@
 | 
			
		||||
							<td><a href="{{AppSubUrl}}/admin/auths/{{.ID}}">{{.Name}}</a></td>
 | 
			
		||||
							<td>{{.TypeName}}</td>
 | 
			
		||||
							<td><i class="fa fa{{if .IsActived}}-check{{end}}-square-o"></i></td>
 | 
			
		||||
							<td><span class="poping up" data-content="{{DateFmtLong .Updated}}" data-variation="tiny">{{DateFmtShort .Updated}}</span></td>
 | 
			
		||||
							<td><span class="poping up" data-content="{{DateFmtLong .Created}}" data-variation="tiny">{{DateFmtShort .Created}}</span></td>
 | 
			
		||||
							<td><span class="poping up" data-content="{{.UpdatedUnix.FormatShort}}" data-variation="tiny">{{.UpdatedUnix.FormatShort}}</span></td>
 | 
			
		||||
							<td><span class="poping up" data-content="{{.CreatedUnix.FormatLong}}" data-variation="tiny">{{.CreatedUnix.FormatShort}}</span></td>
 | 
			
		||||
							<td><a href="{{AppSubUrl}}/admin/auths/{{.ID}}"><i class="fa fa-pencil-square-o"></i></a></td>
 | 
			
		||||
						</tr>
 | 
			
		||||
					{{end}}
 | 
			
		||||
 
 | 
			
		||||
@@ -49,8 +49,8 @@
 | 
			
		||||
						<tr>
 | 
			
		||||
							<td>{{.PID}}</td>
 | 
			
		||||
							<td>{{.Description}}</td>
 | 
			
		||||
							<td>{{DateFmtLong .Start}}</td>
 | 
			
		||||
							<td>{{TimeSince .Start $.Lang}}</td>
 | 
			
		||||
							<td>{{.Start.FormatLong}}</td>
 | 
			
		||||
							<td>{{TimeSinceUnix .Start $.Lang}}</td>
 | 
			
		||||
						</tr>
 | 
			
		||||
					{{end}}
 | 
			
		||||
				</tbody>
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,7 @@
 | 
			
		||||
							<td>{{.ID}}</td>
 | 
			
		||||
							<td>{{$.i18n.Tr .TrStr}}</td>
 | 
			
		||||
							<td>{{SubStr .Description 0 120}}...</td>
 | 
			
		||||
							<td><span class="poping up" data-content="{{.Created}}" data-variation="inverted tiny">{{DateFmtShort .Created}}</span></td>
 | 
			
		||||
							<td><span class="poping up" data-content="{{.CreatedUnix.AsTime}}" data-variation="inverted tiny">{{.CreatedUnix.FormatShort}}</span></td>
 | 
			
		||||
							<td><a href="#"><i class="browser icon view-detail" data-content="{{.Description}}"></i></a></td>
 | 
			
		||||
						</tr>
 | 
			
		||||
					{{end}}
 | 
			
		||||
 
 | 
			
		||||
@@ -33,7 +33,7 @@
 | 
			
		||||
							<td>{{.NumTeams}}</td>
 | 
			
		||||
							<td>{{.NumMembers}}</td>
 | 
			
		||||
							<td>{{.NumRepos}}</td>
 | 
			
		||||
							<td><span title="{{DateFmtLong .Created}}">{{DateFmtShort .Created}}</span></td>
 | 
			
		||||
							<td><span title="{{.CreatedUnix.FormatLong}}">{{.CreatedUnix.FormatShort}}</span></td>
 | 
			
		||||
							<td><a href="{{AppSubUrl}}/org/{{.Name}}/settings"><i class="fa fa-pencil-square-o"></i></a></td>
 | 
			
		||||
						</tr>
 | 
			
		||||
					{{end}}
 | 
			
		||||
 
 | 
			
		||||
@@ -36,7 +36,7 @@
 | 
			
		||||
							<td>{{.NumStars}}</td>
 | 
			
		||||
							<td>{{.NumIssues}}</td>
 | 
			
		||||
							<td>{{SizeFmt .Size}}</td>
 | 
			
		||||
							<td><span title="{{DateFmtLong .Created}}">{{DateFmtShort .Created}}</span></td>
 | 
			
		||||
							<td><span title="{{.CreatedUnix.FormatLong}}">{{.CreatedUnix.FormatShort}}</span></td>
 | 
			
		||||
							<td><a class="delete-button" href="" data-url="{{$.Link}}/delete?page={{$.Page.Current}}" data-id="{{.ID}}"><i class="trash icon text red"></i></a></td>
 | 
			
		||||
						</tr>
 | 
			
		||||
					{{end}}
 | 
			
		||||
 
 | 
			
		||||
@@ -36,9 +36,9 @@
 | 
			
		||||
							<td><i class="fa fa{{if .IsActive}}-check{{end}}-square-o"></i></td>
 | 
			
		||||
							<td><i class="fa fa{{if .IsAdmin}}-check{{end}}-square-o"></i></td>
 | 
			
		||||
							<td>{{.NumRepos}}</td>
 | 
			
		||||
							<td><span title="{{DateFmtLong .Created}}">{{DateFmtShort .Created }}</span></td>
 | 
			
		||||
							<td><span title="{{.CreatedUnix.FormatLong}}">{{.CreatedUnix.FormatShort}}</span></td>
 | 
			
		||||
							{{if .LastLoginUnix}}
 | 
			
		||||
								<td><span title="{{DateFmtLong .LastLogin}}">{{DateFmtShort .LastLogin }}</span></td>
 | 
			
		||||
								<td><span title="{{.LastLoginUnix.FormatLong}}">{{.LastLoginUnix.FormatShort}}</span></td>
 | 
			
		||||
							{{else}}
 | 
			
		||||
								<td><span>{{$.i18n.Tr "admin.users.never_login"}}</span></td>
 | 
			
		||||
							{{end}}
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,7 @@
 | 
			
		||||
								<i class="octicon octicon-link"></i>
 | 
			
		||||
								<a href="{{.Website}}" rel="nofollow">{{.Website}}</a>
 | 
			
		||||
							{{end}}
 | 
			
		||||
							<i class="octicon octicon-clock"></i> {{$.i18n.Tr "user.join_on"}} {{DateFmtShort .Created}}
 | 
			
		||||
							<i class="octicon octicon-clock"></i> {{$.i18n.Tr "user.join_on"}} {{.CreatedUnix.FormatShort}}
 | 
			
		||||
					</div>
 | 
			
		||||
				  </div>
 | 
			
		||||
				</div>
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,7 @@
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
			{{if .DescriptionHTML}}<p class="has-emoji">{{.DescriptionHTML}}</p>{{end}}
 | 
			
		||||
			<p class="time">{{$.i18n.Tr "org.repo_updated"}} {{TimeSince .Updated $.i18n.Lang}}</p>
 | 
			
		||||
			<p class="time">{{$.i18n.Tr "org.repo_updated"}} {{TimeSinceUnix .UpdatedUnix $.i18n.Lang}}</p>
 | 
			
		||||
		</div>
 | 
			
		||||
	{{else}}
 | 
			
		||||
	<div>
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,7 @@
 | 
			
		||||
								<i class="octicon octicon-mail"></i>
 | 
			
		||||
								<a href="mailto:{{.Email}}" rel="nofollow">{{.Email}}</a>
 | 
			
		||||
							{{end}}
 | 
			
		||||
							<i class="octicon octicon-clock"></i> {{$.i18n.Tr "user.join_on"}} {{DateFmtShort .Created}}
 | 
			
		||||
							<i class="octicon octicon-clock"></i> {{$.i18n.Tr "user.join_on"}} {{.CreatedUnix.FormatShort}}
 | 
			
		||||
					</div>
 | 
			
		||||
				  </div>
 | 
			
		||||
				</div>
 | 
			
		||||
 
 | 
			
		||||
@@ -86,7 +86,7 @@
 | 
			
		||||
						{{if not .IsTag}}
 | 
			
		||||
							<a class="title has-emoji" href="{{$.Repository.HTMLURL}}/src/{{.TagName}}">{{.Title}}</a>
 | 
			
		||||
						{{end}}
 | 
			
		||||
						{{TimeSince .Created $.Lang}}
 | 
			
		||||
						{{TimeSinceUnix .CreatedUnix $.Lang}}
 | 
			
		||||
					</p>
 | 
			
		||||
				{{end}}
 | 
			
		||||
			</div>
 | 
			
		||||
@@ -102,7 +102,7 @@
 | 
			
		||||
					<p class="desc">
 | 
			
		||||
						<div class="ui purple label">{{$.i18n.Tr "repo.activity.merged_prs_label"}}</div>
 | 
			
		||||
						#{{.Index}} <a class="title has-emoji" href="{{$.Repository.HTMLURL}}/pulls/{{.Index}}">{{.Issue.Title}}</a>
 | 
			
		||||
						{{TimeSince .Merged $.Lang}}
 | 
			
		||||
						{{TimeSinceUnix .MergedUnix $.Lang}}
 | 
			
		||||
					</p>
 | 
			
		||||
				{{end}}
 | 
			
		||||
			</div>
 | 
			
		||||
@@ -118,7 +118,7 @@
 | 
			
		||||
					<p class="desc">
 | 
			
		||||
						<div class="ui green label">{{$.i18n.Tr "repo.activity.opened_prs_label"}}</div>
 | 
			
		||||
						#{{.Index}} <a class="title has-emoji" href="{{$.Repository.HTMLURL}}/pulls/{{.Index}}">{{.Issue.Title}}</a>
 | 
			
		||||
						{{TimeSince .Issue.Created $.Lang}}
 | 
			
		||||
						{{TimeSinceUnix .Issue.CreatedUnix $.Lang}}
 | 
			
		||||
					</p>
 | 
			
		||||
				{{end}}
 | 
			
		||||
			</div>
 | 
			
		||||
@@ -134,7 +134,7 @@
 | 
			
		||||
					<p class="desc">
 | 
			
		||||
						<div class="ui red label">{{$.i18n.Tr "repo.activity.closed_issue_label"}}</div>
 | 
			
		||||
						#{{.Index}} <a class="title has-emoji" href="{{$.Repository.HTMLURL}}/issues/{{.Index}}">{{.Title}}</a>
 | 
			
		||||
						{{TimeSince .Updated $.Lang}}
 | 
			
		||||
						{{TimeSinceUnix .UpdatedUnix $.Lang}}
 | 
			
		||||
					</p>
 | 
			
		||||
				{{end}}
 | 
			
		||||
			</div>
 | 
			
		||||
@@ -150,7 +150,7 @@
 | 
			
		||||
					<p class="desc">
 | 
			
		||||
						<div class="ui green label">{{$.i18n.Tr "repo.activity.new_issue_label"}}</div>
 | 
			
		||||
						#{{.Index}} <a class="title has-emoji" href="{{$.Repository.HTMLURL}}/issues/{{.Index}}">{{.Title}}</a>
 | 
			
		||||
						{{TimeSince .Created $.Lang}}
 | 
			
		||||
						{{TimeSinceUnix .CreatedUnix $.Lang}}
 | 
			
		||||
					</p>
 | 
			
		||||
				{{end}}
 | 
			
		||||
			</div>
 | 
			
		||||
@@ -174,7 +174,7 @@
 | 
			
		||||
						{{else}}
 | 
			
		||||
						<a class="title has-emoji" href="{{$.Repository.HTMLURL}}/issues/{{.Index}}">{{.Title}}</a>
 | 
			
		||||
						{{end}}
 | 
			
		||||
						{{TimeSince .Updated $.Lang}}
 | 
			
		||||
						{{TimeSinceUnix .UpdatedUnix $.Lang}}
 | 
			
		||||
					</p>
 | 
			
		||||
				{{end}}
 | 
			
		||||
			</div>
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,7 @@
 | 
			
		||||
									<td>
 | 
			
		||||
									{{if .IsDeleted}}
 | 
			
		||||
										<s>{{.Name}}</s>
 | 
			
		||||
										<p class="time">{{$.i18n.Tr "repo.branch.deleted_by" .DeletedBranch.DeletedBy.Name}} {{TimeSince .DeletedBranch.Deleted $.i18n.Lang}}</p>
 | 
			
		||||
										<p class="time">{{$.i18n.Tr "repo.branch.deleted_by" .DeletedBranch.DeletedBy.Name}} {{TimeSinceUnix .DeletedBranch.DeletedUnix $.i18n.Lang}}</p>
 | 
			
		||||
									{{else}}
 | 
			
		||||
										{{.Name}}
 | 
			
		||||
										<p class="time">{{$.i18n.Tr "org.repo_updated"}} {{TimeSince .Commit.Committer.When $.i18n.Lang}}</p>
 | 
			
		||||
 
 | 
			
		||||
@@ -163,7 +163,7 @@
 | 
			
		||||
 | 
			
		||||
		<div class="issue list">
 | 
			
		||||
			{{range .Issues}}
 | 
			
		||||
				{{ $timeStr:= TimeSince .Created $.Lang }}
 | 
			
		||||
				{{ $timeStr:= TimeSinceUnix .CreatedUnix $.Lang }}
 | 
			
		||||
				<li class="item">
 | 
			
		||||
					<div class="ui checkbox issue-checkbox">
 | 
			
		||||
						<input type="checkbox" data-issue-id={{.ID}}></input>
 | 
			
		||||
 
 | 
			
		||||
@@ -50,7 +50,7 @@
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
					<div class="meta">
 | 
			
		||||
						{{ $closedDate:= TimeSince .ClosedDate $.Lang }}
 | 
			
		||||
						{{ $closedDate:= TimeSinceUnix .ClosedDateUnix $.Lang }}
 | 
			
		||||
						{{if .IsClosed}}
 | 
			
		||||
							<span class="octicon octicon-clock"></span> {{$.i18n.Tr "repo.milestones.closed" $closedDate|Str2html}}
 | 
			
		||||
						{{else}}
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
		{{template "repo/issue/view_title" .}}
 | 
			
		||||
	{{end}}
 | 
			
		||||
 | 
			
		||||
	{{ $createdStr:= TimeSince .Issue.Created $.Lang }}
 | 
			
		||||
	{{ $createdStr:= TimeSinceUnix .Issue.CreatedUnix $.Lang }}
 | 
			
		||||
	<div class="twelve wide column comment-list">
 | 
			
		||||
		<ui class="ui comments">
 | 
			
		||||
			<div class="comment">
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
{{range .Issue.Comments}}
 | 
			
		||||
	{{ $createdStr:= TimeSince .Created $.Lang }}
 | 
			
		||||
	{{ $createdStr:= TimeSinceUnix .CreatedUnix $.Lang }}
 | 
			
		||||
 | 
			
		||||
	<!-- 0 = COMMENT, 1 = REOPEN, 2 = CLOSE, 3 = ISSUE_REF, 4 = COMMIT_REF, 5 = COMMENT_REF, 6 = PULL_REF, 7 = COMMENT_LABEL, 12 = START_TRACKING, 13 = STOP_TRACKING, 14 = ADD_TIME_MANUAL -->
 | 
			
		||||
	{{if eq .Type 0}}
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,7 @@
 | 
			
		||||
 | 
			
		||||
	{{if .Issue.IsPull}}
 | 
			
		||||
		{{if .Issue.PullRequest.HasMerged}}
 | 
			
		||||
			{{ $mergedStr:= TimeSince .Issue.PullRequest.Merged $.Lang }}
 | 
			
		||||
			{{ $mergedStr:= TimeSinceUnix .Issue.PullRequest.MergedUnix $.Lang }}
 | 
			
		||||
			<a {{if gt .Issue.PullRequest.Merger.ID 0}}href="{{.Issue.PullRequest.Merger.HomeLink}}"{{end}}>{{.Issue.PullRequest.Merger.Name}}</a>
 | 
			
		||||
			<span class="pull-desc">{{$.i18n.Tr "repo.pulls.merged_title_desc" .NumCommits .HeadTarget .BaseTarget $mergedStr | Str2html}}</span>
 | 
			
		||||
		{{else}}
 | 
			
		||||
@@ -34,7 +34,7 @@
 | 
			
		||||
			<span class="pull-desc">{{$.i18n.Tr "repo.pulls.title_desc" .NumCommits .HeadTarget .BaseTarget | Str2html}}</span>
 | 
			
		||||
		{{end}}
 | 
			
		||||
	{{else}}
 | 
			
		||||
		{{ $createdStr:= TimeSince .Issue.Created $.Lang }}
 | 
			
		||||
		{{ $createdStr:= TimeSinceUnix .Issue.CreatedUnix $.Lang }}
 | 
			
		||||
		<span class="time-desc">
 | 
			
		||||
			{{if gt .Issue.Poster.ID 0}}
 | 
			
		||||
				{{$.i18n.Tr "repo.issues.opened_by" $createdStr .Issue.Poster.HomeLink .Issue.Poster.Name | Safe}}
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,7 @@
 | 
			
		||||
				<li class="ui grid">
 | 
			
		||||
					<div class="ui four wide column meta">
 | 
			
		||||
						{{if .IsTag}}
 | 
			
		||||
							{{if .Created}}<span class="time">{{TimeSince .Created $.Lang}}</span>{{end}}
 | 
			
		||||
							{{if .CreatedUnix}}<span class="time">{{TimeSinceUnix .CreatedUnix $.Lang}}</span>{{end}}
 | 
			
		||||
						{{else}}
 | 
			
		||||
							{{if .IsDraft}}
 | 
			
		||||
								<span class="ui yellow label">{{$.i18n.Tr "repo.release.draft"}}</span>
 | 
			
		||||
@@ -55,7 +55,7 @@
 | 
			
		||||
									<img class="img-10" src="{{.Publisher.RelAvatarLink}}">
 | 
			
		||||
									<a href="{{AppSubUrl}}/{{.Publisher.Name}}">{{.Publisher.Name}}</a>
 | 
			
		||||
								</span>
 | 
			
		||||
								{{if .Created}}<span class="time">{{TimeSince .Created $.Lang}}</span>{{end}}
 | 
			
		||||
								{{if .CreatedUnix}}<span class="time">{{TimeSinceUnix .CreatedUnix $.Lang}}</span>{{end}}
 | 
			
		||||
								<span class="ahead">{{$.i18n.Tr "repo.release.ahead" .NumCommitsBehind .Target | Str2html}}</span>
 | 
			
		||||
							</p>
 | 
			
		||||
							<div class="markdown desc">
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,7 @@
 | 
			
		||||
										{{.Fingerprint}}
 | 
			
		||||
									</div>
 | 
			
		||||
									<div class="activity meta">
 | 
			
		||||
										<i>{{$.i18n.Tr "settings.add_on"}} <span>{{DateFmtShort .Created}}</span> —  <i class="octicon octicon-info"></i> {{if .HasUsed}}{{$.i18n.Tr "settings.last_used"}} <span {{if .HasRecentActivity}}class="green"{{end}}>{{DateFmtShort .Updated}}</span>{{else}}{{$.i18n.Tr "settings.no_activity"}}{{end}}</i>
 | 
			
		||||
										<i>{{$.i18n.Tr "settings.add_on"}} <span>{{.CreatedUnix.FormatShort}}</span> —  <i class="octicon octicon-info"></i> {{if .HasUsed}}{{$.i18n.Tr "settings.last_used"}} <span {{if .HasRecentActivity}}class="green"{{end}}>{{.UpdatedUnix.FormatShort}}</span>{{else}}{{$.i18n.Tr "settings.no_activity"}}{{end}}</i>
 | 
			
		||||
									</div>
 | 
			
		||||
								</div>
 | 
			
		||||
						</div>
 | 
			
		||||
 
 | 
			
		||||
@@ -76,7 +76,7 @@
 | 
			
		||||
					<input type="hidden" name="action" value="mirror-sync">
 | 
			
		||||
					<div class="inline field">
 | 
			
		||||
						<label>{{.i18n.Tr "repo.mirror_last_synced"}}</label>
 | 
			
		||||
						<span>{{.Mirror.Updated}}</span>
 | 
			
		||||
						<span>{{.Mirror.UpdatedUnix.AsTime}}</span>
 | 
			
		||||
					</div>
 | 
			
		||||
					<div class="field">
 | 
			
		||||
						<button class="ui blue button">{{$.i18n.Tr "repo.settings.sync_mirror"}}</button>
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@
 | 
			
		||||
					{{else if .Location}}
 | 
			
		||||
						<span class="octicon octicon-location"></span> {{.Location}}
 | 
			
		||||
					{{else}}
 | 
			
		||||
						<span class="octicon octicon-clock"></span> {{$.i18n.Tr "user.join_on"}} {{DateFmtShort .Created}}
 | 
			
		||||
						<span class="octicon octicon-clock"></span> {{$.i18n.Tr "user.join_on"}} {{.CreatedUnix.FormatShort}}
 | 
			
		||||
					{{end}}
 | 
			
		||||
				</div>
 | 
			
		||||
			</li>
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,7 @@
 | 
			
		||||
							<i class="octicon octicon-file-text"></i>
 | 
			
		||||
							<a href="{{$.RepoLink}}/wiki/{{.SubURL}}">{{.Name}}</a>
 | 
			
		||||
						</td>
 | 
			
		||||
						{{$timeSince := TimeSince .Updated $.Lang}}
 | 
			
		||||
						{{$timeSince := TimeSinceUnix .UpdatedUnix $.Lang}}
 | 
			
		||||
						<td class="text right grey">{{$.i18n.Tr "repo.wiki.last_updated" $timeSince | Safe}}</td>
 | 
			
		||||
					</tr>
 | 
			
		||||
				{{end}}
 | 
			
		||||
 
 | 
			
		||||
@@ -59,7 +59,7 @@
 | 
			
		||||
 | 
			
		||||
				<div class="issue list">
 | 
			
		||||
					{{range .Issues}}
 | 
			
		||||
						{{ $timeStr:= TimeSince .Created $.Lang }}
 | 
			
		||||
						{{ $timeStr:= TimeSinceUnix .CreatedUnix $.Lang }}
 | 
			
		||||
						<li class="item">
 | 
			
		||||
							<div class="ui label">{{if not $.RepoID}}{{.Repo.FullName}}{{end}}#{{.Index}}</div>
 | 
			
		||||
							<a class="title has-emoji" href="{{AppSubUrl}}/{{.Repo.Owner.Name}}/{{.Repo.Name}}/issues/{{.Index}}">{{.Title}}</a>
 | 
			
		||||
 
 | 
			
		||||
@@ -42,7 +42,7 @@
 | 
			
		||||
									</li>
 | 
			
		||||
								{{end}}
 | 
			
		||||
							{{end}}
 | 
			
		||||
							<li><i class="octicon octicon-clock"></i> {{.i18n.Tr "user.join_on"}} {{DateFmtShort .Owner.Created}}</li>
 | 
			
		||||
							<li><i class="octicon octicon-clock"></i> {{.i18n.Tr "user.join_on"}} {{.Owner.CreatedUnix.FormatShort}}</li>
 | 
			
		||||
							<li>
 | 
			
		||||
								<i class="octicon octicon-person"></i>
 | 
			
		||||
								<a href="{{.Owner.HomeLink}}/followers">
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,7 @@
 | 
			
		||||
							<div class="content">
 | 
			
		||||
								<strong>{{.Name}}</strong>
 | 
			
		||||
								<div class="activity meta">
 | 
			
		||||
									<i>{{$.i18n.Tr "settings.add_on"}} <span>{{DateFmtShort .Created}}</span> —  <i class="octicon octicon-info"></i> {{if .HasUsed}}{{$.i18n.Tr "settings.last_used"}} <span {{if .HasRecentActivity}}class="green"{{end}}>{{DateFmtShort .Updated}}</span>{{else}}{{$.i18n.Tr "settings.no_activity"}}{{end}}</i>
 | 
			
		||||
									<i>{{$.i18n.Tr "settings.add_on"}} <span>{{.CreatedUnix.FormatShort}}</span> —  <i class="octicon octicon-info"></i> {{if .HasUsed}}{{$.i18n.Tr "settings.last_used"}} <span {{if .HasRecentActivity}}class="green"{{end}}>{{.UpdatedUnix.FormatShort}}</span>{{else}}{{$.i18n.Tr "settings.no_activity"}}{{end}}</i>
 | 
			
		||||
								</div>
 | 
			
		||||
							</div>
 | 
			
		||||
					</div>
 | 
			
		||||
 
 | 
			
		||||
@@ -24,9 +24,9 @@
 | 
			
		||||
						<b>{{$.i18n.Tr "settings.subkeys"}}:</b> {{range .SubsKey}} {{.KeyID}} {{end}}
 | 
			
		||||
					</div>
 | 
			
		||||
					<div class="activity meta">
 | 
			
		||||
						<i>{{$.i18n.Tr "settings.add_on"}} <span>{{DateFmtShort .Added}}</span></i>
 | 
			
		||||
						<i>{{$.i18n.Tr "settings.add_on"}} <span>{{.AddedUnix.FormatShort}}</span></i>
 | 
			
		||||
						-
 | 
			
		||||
						<i>{{if not .Expired.IsZero }}{{$.i18n.Tr "settings.valid_until"}} <span>{{DateFmtShort .Expired}}</span>{{else}}{{$.i18n.Tr "settings.valid_forever"}}{{end}}</i>
 | 
			
		||||
						<i>{{if .ExpiredUnix}}{{$.i18n.Tr "settings.valid_until"}} <span>{{.ExpiredUnix.FormatShort}}</span>{{else}}{{$.i18n.Tr "settings.valid_forever"}}{{end}}</i>
 | 
			
		||||
					</div>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
 
 | 
			
		||||
@@ -27,7 +27,7 @@
 | 
			
		||||
                        {{.Fingerprint}}
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="activity meta">
 | 
			
		||||
                        <i>{{$.i18n.Tr "settings.add_on"}} <span>{{DateFmtShort .Created}}</span> —	<i class="octicon octicon-info"></i> {{if .HasUsed}}{{$.i18n.Tr "settings.last_used"}} <span {{if .HasRecentActivity}}class="green"{{end}}>{{DateFmtShort .Updated}}</span>{{else}}{{$.i18n.Tr "settings.no_activity"}}{{end}}</i>
 | 
			
		||||
                        <i>{{$.i18n.Tr "settings.add_on"}} <span>{{.CreatedUnix.FormatShort}}</span> —	<i class="octicon octicon-info"></i> {{if .HasUsed}}{{$.i18n.Tr "settings.last_used"}} <span {{if .HasRecentActivity}}class="green"{{end}}>{{.UpdatedUnix.FormatShort}}</span>{{else}}{{$.i18n.Tr "settings.no_activity"}}{{end}}</i>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
			</div>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user