From f2e20c81b66e6a937ecdb686f8d1011371433365 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 11 Dec 2017 12:37:04 +0800 Subject: [PATCH] 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 --- models/action.go | 15 ++--- models/admin.go | 11 +--- models/attachment.go | 13 +---- models/branches.go | 30 ++++------ models/gpg_key.go | 36 +++++------- models/gpg_key_test.go | 6 +- models/issue.go | 29 ++-------- models/issue_comment.go | 15 ++--- models/issue_comment_test.go | 4 +- models/issue_milestone.go | 31 ++++------ models/issue_milestone_test.go | 5 +- models/issue_reaction.go | 22 +++---- models/issue_stopwatch.go | 25 +++----- models/issue_stopwatch_test.go | 5 +- models/issue_test.go | 2 +- models/issue_watch.go | 40 +++---------- models/lfs.go | 21 +++---- models/login_source.go | 14 +---- models/notification.go | 32 ++--------- models/pull.go | 39 ++++--------- models/release.go | 39 ++++--------- models/repo.go | 21 +++---- models/repo_mirror.go | 25 ++------ models/repo_unit.go | 11 +--- models/ssh_key.go | 19 +++---- models/status.go | 19 ++----- models/token.go | 17 +++--- models/twofactor.go | 15 +---- models/update.go | 7 +-- models/user.go | 14 ++--- models/webhook.go | 10 +--- modules/auth/auth.go | 4 +- modules/base/tool.go | 22 ++++++- modules/templates/helper.go | 17 +++--- modules/util/time_stamp.go | 57 +++++++++++++++++++ routers/api/v1/convert/convert.go | 14 ++--- routers/api/v1/repo/milestone.go | 11 ++-- routers/api/v1/user/watch.go | 4 +- routers/repo/http.go | 3 +- routers/repo/issue.go | 12 ++-- routers/repo/setting.go | 3 +- templates/admin/auth/list.tmpl | 4 +- templates/admin/monitor.tmpl | 4 +- templates/admin/notice.tmpl | 2 +- templates/admin/org/list.tmpl | 2 +- templates/admin/repo/list.tmpl | 2 +- templates/admin/user/list.tmpl | 4 +- templates/explore/organizations.tmpl | 2 +- templates/explore/repo_list.tmpl | 2 +- templates/explore/users.tmpl | 2 +- templates/repo/activity.tmpl | 12 ++-- templates/repo/branch/list.tmpl | 2 +- templates/repo/issue/list.tmpl | 2 +- templates/repo/issue/milestones.tmpl | 2 +- templates/repo/issue/view_content.tmpl | 2 +- .../repo/issue/view_content/comments.tmpl | 2 +- templates/repo/issue/view_title.tmpl | 4 +- templates/repo/release/list.tmpl | 4 +- templates/repo/settings/deploy_keys.tmpl | 2 +- templates/repo/settings/options.tmpl | 2 +- templates/repo/user_cards.tmpl | 2 +- templates/repo/wiki/pages.tmpl | 2 +- templates/user/dashboard/issues.tmpl | 2 +- templates/user/profile.tmpl | 2 +- templates/user/settings/applications.tmpl | 2 +- templates/user/settings/keys_gpg.tmpl | 4 +- templates/user/settings/keys_ssh.tmpl | 2 +- 67 files changed, 334 insertions(+), 479 deletions(-) create mode 100644 modules/util/time_stamp.go diff --git a/models/action.go b/models/action.go index 699b32f31..5333f6277 100644 --- a/models/action.go +++ b/models/action.go @@ -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" @@ -85,15 +86,9 @@ type Action struct { Comment *Comment `xorm:"-"` IsDeleted bool `xorm:"INDEX NOT NULL DEFAULT false"` 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() + IsPrivate bool `xorm:"INDEX NOT NULL DEFAULT false"` + Content string `xorm:"TEXT"` + 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 diff --git a/models/admin.go b/models/admin.go index ab538c447..06b7c14c6 100644 --- a/models/admin.go +++ b/models/admin.go @@ -6,7 +6,6 @@ package models import ( "fmt" - "time" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/util" @@ -26,14 +25,8 @@ const ( 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() + Description string `xorm:"TEXT"` + CreatedUnix util.TimeStamp `xorm:"INDEX created"` } // TrStr returns a translation format string. diff --git a/models/attachment.go b/models/attachment.go index 9c91613e1..cadb23a57 100644 --- a/models/attachment.go +++ b/models/attachment.go @@ -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. @@ -25,15 +25,8 @@ type Attachment struct { ReleaseID int64 `xorm:"INDEX"` 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() + DownloadCount int64 `xorm:"DEFAULT 0"` + CreatedUnix util.TimeStamp `xorm:"created"` } // IncreaseDownloadCount is update download count + 1 diff --git a/models/branches.go b/models/branches.go index 1c06a0835..7cc0ebab4 100644 --- a/models/branches.go +++ b/models/branches.go @@ -29,12 +29,10 @@ type ProtectedBranch struct { BranchName string `xorm:"UNIQUE(s)"` CanPush bool `xorm:"NOT NULL DEFAULT false"` 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"` + WhitelistUserIDs []int64 `xorm:"JSON TEXT"` + WhitelistTeamIDs []int64 `xorm:"JSON TEXT"` + CreatedUnix util.TimeStamp `xorm:"created"` + UpdatedUnix util.TimeStamp `xorm:"updated"` } // IsProtected returns if the branch is protected @@ -197,19 +195,13 @@ func (repo *Repository) DeleteProtectedBranch(id int64) (err error) { // DeletedBranch struct type DeletedBranch struct { - ID int64 `xorm:"pk autoincr"` - RepoID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"` - Name string `xorm:"UNIQUE(s) NOT NULL"` - 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() + ID int64 `xorm:"pk autoincr"` + RepoID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"` + Name string `xorm:"UNIQUE(s) NOT NULL"` + Commit string `xorm:"UNIQUE(s) NOT NULL"` + DeletedByID int64 `xorm:"INDEX"` + DeletedBy *User `xorm:"-"` + DeletedUnix util.TimeStamp `xorm:"INDEX created"` } // AddDeletedBranch adds a deleted branch to the database diff --git a/models/gpg_key.go b/models/gpg_key.go index 6959f373c..b7d86c8bf 100644 --- a/models/gpg_key.go +++ b/models/gpg_key.go @@ -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" @@ -26,17 +27,14 @@ import ( // GPGKey represents a GPG key. type GPGKey struct { - ID int64 `xorm:"pk autoincr"` - OwnerID int64 `xorm:"INDEX NOT NULL"` - 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 + ID int64 `xorm:"pk autoincr"` + OwnerID int64 `xorm:"INDEX NOT NULL"` + KeyID string `xorm:"INDEX CHAR(16) NOT NULL"` + PrimaryKeyID string `xorm:"CHAR(16)"` + Content string `xorm:"TEXT NOT NULL"` + 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(), diff --git a/models/gpg_key_test.go b/models/gpg_key_test.go index 6b34b1076..4e671b1c2 100644 --- a/models/gpg_key_test.go +++ b/models/gpg_key_test.go @@ -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, diff --git a/models/issue.go b/models/issue.go index 2119dcefd..7cea3b92a 100644 --- a/models/issue.go +++ b/models/issue.go @@ -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() } } diff --git a/models/issue_comment.go b/models/issue_comment.go index aabeb9c8d..2f4ddd63e 100644 --- a/models/issue_comment.go +++ b/models/issue_comment.go @@ -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(), } } diff --git a/models/issue_comment_test.go b/models/issue_comment_test.go index 86fc32a8d..f6a6fbce9 100644 --- a/models/issue_comment_test.go +++ b/models/issue_comment_test.go @@ -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)) } diff --git a/models/issue_milestone.go b/models/issue_milestone.go index 13cbe7ffb..b4ebabf57 100644 --- a/models/issue_milestone.go +++ b/models/issue_milestone.go @@ -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" @@ -27,16 +26,14 @@ type Milestone struct { Completeness int // Percentage(1-100). IsOverDue bool `xorm:"-"` - DeadlineString string `xorm:"-"` - Deadline time.Time `xorm:"-"` - DeadlineUnix int64 - ClosedDate time.Time `xorm:"-"` - ClosedDateUnix int64 + DeadlineString string `xorm:"-"` + 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 } diff --git a/models/issue_milestone_test.go b/models/issue_milestone_test.go index 7926b348c..e0bfe11df 100644 --- a/models/issue_milestone_test.go +++ b/models/issue_milestone_test.go @@ -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()) } diff --git a/models/issue_reaction.go b/models/issue_reaction.go index 3ecf53642..8f3ee7bfe 100644 --- a/models/issue_reaction.go +++ b/models/issue_reaction.go @@ -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" @@ -17,19 +17,13 @@ import ( // Reaction represents a reactions on issues and comments. type Reaction struct { - ID int64 `xorm:"pk autoincr"` - Type string `xorm:"INDEX UNIQUE(s) NOT NULL"` - IssueID int64 `xorm:"INDEX UNIQUE(s) NOT NULL"` - 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() + ID int64 `xorm:"pk autoincr"` + Type string `xorm:"INDEX UNIQUE(s) NOT NULL"` + IssueID int64 `xorm:"INDEX UNIQUE(s) NOT NULL"` + CommentID int64 `xorm:"INDEX UNIQUE(s)"` + UserID int64 `xorm:"INDEX UNIQUE(s) NOT NULL"` + User *User `xorm:"-"` + CreatedUnix util.TimeStamp `xorm:"INDEX created"` } // FindReactionsOptions describes the conditions to Find reactions diff --git a/models/issue_stopwatch.go b/models/issue_stopwatch.go index b136c511f..92b1bb9a5 100644 --- a/models/issue_stopwatch.go +++ b/models/issue_stopwatch.go @@ -7,26 +7,16 @@ package models import ( "fmt" "time" + + "code.gitea.io/gitea/modules/util" ) // Stopwatch represents a stopwatch for time tracking. 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() + ID int64 `xorm:"pk autoincr"` + IssueID int64 `xorm:"INDEX"` + UserID int64 `xorm:"INDEX"` + 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 { diff --git a/models/issue_stopwatch_test.go b/models/issue_stopwatch_test.go index 9875066e5..798324047 100644 --- a/models/issue_stopwatch_test.go +++ b/models/issue_stopwatch_test.go @@ -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}) diff --git a/models/issue_test.go b/models/issue_test.go index 21df146b5..47bb4feea 100644 --- a/models/issue_test.go +++ b/models/issue_test.go @@ -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)) } diff --git a/models/issue_watch.go b/models/issue_watch.go index 9ef1ff500..69e218af0 100644 --- a/models/issue_watch.go +++ b/models/issue_watch.go @@ -4,42 +4,16 @@ package models -import ( - "time" -) +import "code.gitea.io/gitea/modules/util" // IssueWatch is connection request for receiving issue notification. type IssueWatch struct { - ID int64 `xorm:"pk autoincr"` - 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 + ID int64 `xorm:"pk autoincr"` + UserID int64 `xorm:"UNIQUE(watch) NOT NULL"` + IssueID int64 `xorm:"UNIQUE(watch) NOT NULL"` + IsWatching bool `xorm:"NOT NULL"` + CreatedUnix util.TimeStamp `xorm:"created NOT NULL"` + UpdatedUnix util.TimeStamp `xorm:"updated NOT NULL"` } // CreateOrUpdateIssueWatch set watching for a user and issue diff --git a/models/lfs.go b/models/lfs.go index d6cdc6889..711e5b049 100644 --- a/models/lfs.go +++ b/models/lfs.go @@ -2,18 +2,18 @@ package models import ( "errors" - "time" + + "code.gitea.io/gitea/modules/util" ) // LFSMetaObject stores metadata for LFS tracked files. type LFSMetaObject struct { - ID int64 `xorm:"pk autoincr"` - Oid string `xorm:"UNIQUE(s) INDEX NOT NULL"` - Size int64 `xorm:"NOT NULL"` - RepositoryID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"` - Existing bool `xorm:"-"` - Created time.Time `xorm:"-"` - CreatedUnix int64 `xorm:"created"` + ID int64 `xorm:"pk autoincr"` + Oid string `xorm:"UNIQUE(s) INDEX NOT NULL"` + Size int64 `xorm:"NOT NULL"` + RepositoryID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"` + Existing bool `xorm:"-"` + 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() -} diff --git a/models/login_source.go b/models/login_source.go index 9fb056ee5..2c0b4fb5f 100644 --- a/models/login_source.go +++ b/models/login_source.go @@ -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] diff --git a/models/notification.go b/models/notification.go index dcd624e51..c8376a857 100644 --- a/models/notification.go +++ b/models/notification.go @@ -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 diff --git a/models/pull.go b/models/pull.go index 4b928c8d9..47fc1dfb6 100644 --- a/models/pull.go +++ b/models/pull.go @@ -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" @@ -67,27 +68,11 @@ type PullRequest struct { BaseBranch string MergeBase string `xorm:"VARCHAR(40)"` - HasMerged bool `xorm:"INDEX"` - 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() + HasMerged bool `xorm:"INDEX"` + MergedCommitID string `xorm:"VARCHAR(40)"` + MergerID int64 `xorm:"INDEX"` + Merger *User `xorm:"-"` + 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) diff --git a/models/release.go b/models/release.go index ddaf6d6aa..1e1d339a7 100644 --- a/models/release.go +++ b/models/release.go @@ -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" ) @@ -30,28 +30,13 @@ type Release struct { Title string Sha1 string `xorm:"VARCHAR(40)"` NumCommits int64 - NumCommitsBehind int64 `xorm:"-"` - Note string `xorm:"TEXT"` - 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() + NumCommitsBehind int64 `xorm:"-"` + Note string `xorm:"TEXT"` + IsDraft bool `xorm:"NOT NULL DEFAULT false"` + IsPrerelease bool `xorm:"NOT NULL DEFAULT false"` + IsTag bool `xorm:"NOT NULL DEFAULT false"` + Attachments []*Attachment `xorm:"-"` + 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) { diff --git a/models/repo.go b/models/repo.go index 77a960deb..ff0d00308 100644 --- a/models/repo.go +++ b/models/repo.go @@ -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, } } @@ -1011,10 +1008,10 @@ func MigrateRepository(doer, u *User, opts MigrateRepoOptions) (*Repository, err if opts.IsMirror { if _, err = x.InsertOne(&Mirror{ - RepoID: repo.ID, - Interval: setting.Mirror.DefaultInterval, - EnablePrune: true, - NextUpdate: time.Now().Add(setting.Mirror.DefaultInterval), + RepoID: repo.ID, + Interval: setting.Mirror.DefaultInterval, + EnablePrune: true, + NextUpdateUnix: util.TimeStampNow().AddDuration(setting.Mirror.DefaultInterval), }); err != nil { return repo, fmt.Errorf("InsertOne: %v", err) } diff --git a/models/repo_mirror.go b/models/repo_mirror.go index f52b3eb45..197889e19 100644 --- a/models/repo_mirror.go +++ b/models/repo_mirror.go @@ -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 } diff --git a/models/repo_unit.go b/models/repo_unit.go index 3f0e65f9a..5100ca1ce 100644 --- a/models/repo_unit.go +++ b/models/repo_unit.go @@ -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] diff --git a/models/ssh_key.go b/models/ssh_key.go index 9365fab1a..ea313f147 100644 --- a/models/ssh_key.go +++ b/models/ssh_key.go @@ -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"` - HasRecentActivity bool `xorm:"-"` - HasUsed bool `xorm:"-"` + 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 diff --git a/models/status.go b/models/status.go index e2e8adb77..3146f8d30 100644 --- a/models/status.go +++ b/models/status.go @@ -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, diff --git a/models/token.go b/models/token.go index c28292482..8393a7cf1 100644 --- a/models/token.go +++ b/models/token.go @@ -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"` - HasRecentActivity bool `xorm:"-"` - HasUsed bool `xorm:"-"` + 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. diff --git a/models/twofactor.go b/models/twofactor.go index 86718b4cd..36ff5db42 100644 --- a/models/twofactor.go +++ b/models/twofactor.go @@ -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. diff --git a/models/update.go b/models/update.go index f91559d9e..b1bbe0754 100644 --- a/models/update.go +++ b/models/update.go @@ -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 { diff --git a/models/user.go b/models/user.go index 61c2ac47a..0a2e2e9f9 100644 --- a/models/user.go +++ b/models/user.go @@ -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. diff --git a/models/webhook.go b/models/webhook.go index 1b601b4e6..3e3f5fc3f 100644 --- a/models/webhook.go +++ b/models/webhook.go @@ -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 diff --git a/modules/auth/auth.go b/modules/auth/auth.go index 89b3e3850..f3aac5189 100644 --- a/modules/auth/auth.go +++ b/modules/auth/auth.go @@ -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) } diff --git a/modules/base/tool.go b/modules/base/tool.go index 1316b8fad..347241e6b 100644 --- a/modules/base/tool.go +++ b/modules/base/tool.go @@ -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(`%s`, + then.Format(setting.TimeFormat), + timeSinceUnix(int64(then), int64(now), lang))) +} + // Storage space size types const ( Byte = 1 diff --git a/modules/templates/helper.go b/modules/templates/helper.go index c8b872d9f..d6be25ceb 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -65,14 +65,15 @@ func NewFuncMap() []template.FuncMap { "LoadTimes": func(startTime time.Time) string { return fmt.Sprint(time.Since(startTime).Nanoseconds()/1e6) + "ms" }, - "AvatarLink": base.AvatarLink, - "Safe": Safe, - "SafeJS": SafeJS, - "Str2html": Str2html, - "TimeSince": base.TimeSince, - "RawTimeSince": base.RawTimeSince, - "FileSize": base.FileSize, - "Subtract": base.Subtract, + "AvatarLink": base.AvatarLink, + "Safe": Safe, + "SafeJS": SafeJS, + "Str2html": Str2html, + "TimeSince": base.TimeSince, + "TimeSinceUnix": base.TimeSinceUnix, + "RawTimeSince": base.RawTimeSince, + "FileSize": base.FileSize, + "Subtract": base.Subtract, "Add": func(a, b int) int { return a + b }, diff --git a/modules/util/time_stamp.go b/modules/util/time_stamp.go new file mode 100644 index 000000000..4a12a2cab --- /dev/null +++ b/modules/util/time_stamp.go @@ -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") +} diff --git a/routers/api/v1/convert/convert.go b/routers/api/v1/convert/convert.go index b5aad95a9..1bfd7f1ff 100644 --- a/routers/api/v1/convert/convert.go +++ b/routers/api/v1/convert/convert.go @@ -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(), } } diff --git a/routers/api/v1/repo/milestone.go b/routers/api/v1/repo/milestone.go index 0e597a9db..29bab67ac 100644 --- a/routers/api/v1/repo/milestone.go +++ b/routers/api/v1/repo/milestone.go @@ -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 @@ -118,10 +119,10 @@ func CreateMilestone(ctx *context.APIContext, form api.CreateMilestoneOption) { } milestone := &models.Milestone{ - RepoID: ctx.Repo.Repository.ID, - Name: form.Title, - Content: form.Description, - Deadline: *form.Deadline, + RepoID: ctx.Repo.Repository.ID, + Name: form.Title, + Content: form.Description, + 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 { diff --git a/routers/api/v1/user/watch.go b/routers/api/v1/user/watch.go index b10831f5f..af7b9b4cc 100644 --- a/routers/api/v1/user/watch.go +++ b/routers/api/v1/user/watch.go @@ -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), }) diff --git a/routers/repo/http.go b/routers/repo/http.go index c5b45f9cc..c1fdad535 100644 --- a/routers/repo/http.go +++ b/routers/repo/http.go @@ -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) } diff --git a/routers/repo/issue.go b/routers/repo/issue.go index 884a80518..ba68b49ad 100644 --- a/routers/repo/issue.go +++ b/routers/repo/issue.go @@ -1138,10 +1138,10 @@ func NewMilestonePost(ctx *context.Context, form auth.CreateMilestoneForm) { } if err = models.NewMilestone(&models.Milestone{ - RepoID: ctx.Repo.Repository.ID, - Name: form.Title, - Content: form.Content, - Deadline: deadline, + RepoID: ctx.Repo.Repository.ID, + Name: form.Title, + Content: form.Content, + 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 diff --git a/routers/repo/setting.go b/routers/repo/setting.go index 16cc699ae..329802673 100644 --- a/routers/repo/setting.go +++ b/routers/repo/setting.go @@ -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 diff --git a/templates/admin/auth/list.tmpl b/templates/admin/auth/list.tmpl index 4e8fb1ea8..60b8f6fbe 100644 --- a/templates/admin/auth/list.tmpl +++ b/templates/admin/auth/list.tmpl @@ -29,8 +29,8 @@ {{.Name}} {{.TypeName}} - {{DateFmtShort .Updated}} - {{DateFmtShort .Created}} + {{.UpdatedUnix.FormatShort}} + {{.CreatedUnix.FormatShort}} {{end}} diff --git a/templates/admin/monitor.tmpl b/templates/admin/monitor.tmpl index 6cc927d68..ceca29146 100644 --- a/templates/admin/monitor.tmpl +++ b/templates/admin/monitor.tmpl @@ -49,8 +49,8 @@ {{.PID}} {{.Description}} - {{DateFmtLong .Start}} - {{TimeSince .Start $.Lang}} + {{.Start.FormatLong}} + {{TimeSinceUnix .Start $.Lang}} {{end}} diff --git a/templates/admin/notice.tmpl b/templates/admin/notice.tmpl index 49e760d2b..745433d18 100644 --- a/templates/admin/notice.tmpl +++ b/templates/admin/notice.tmpl @@ -29,7 +29,7 @@ {{.ID}} {{$.i18n.Tr .TrStr}} {{SubStr .Description 0 120}}... - {{DateFmtShort .Created}} + {{.CreatedUnix.FormatShort}} {{end}} diff --git a/templates/admin/org/list.tmpl b/templates/admin/org/list.tmpl index 362352b69..141628c5b 100644 --- a/templates/admin/org/list.tmpl +++ b/templates/admin/org/list.tmpl @@ -33,7 +33,7 @@ {{.NumTeams}} {{.NumMembers}} {{.NumRepos}} - {{DateFmtShort .Created}} + {{.CreatedUnix.FormatShort}} {{end}} diff --git a/templates/admin/repo/list.tmpl b/templates/admin/repo/list.tmpl index aeaecf8df..470be359e 100644 --- a/templates/admin/repo/list.tmpl +++ b/templates/admin/repo/list.tmpl @@ -36,7 +36,7 @@ {{.NumStars}} {{.NumIssues}} {{SizeFmt .Size}} - {{DateFmtShort .Created}} + {{.CreatedUnix.FormatShort}} {{end}} diff --git a/templates/admin/user/list.tmpl b/templates/admin/user/list.tmpl index 7e0641701..d590526ca 100644 --- a/templates/admin/user/list.tmpl +++ b/templates/admin/user/list.tmpl @@ -36,9 +36,9 @@ {{.NumRepos}} - {{DateFmtShort .Created }} + {{.CreatedUnix.FormatShort}} {{if .LastLoginUnix}} - {{DateFmtShort .LastLogin }} + {{.LastLoginUnix.FormatShort}} {{else}} {{$.i18n.Tr "admin.users.never_login"}} {{end}} diff --git a/templates/explore/organizations.tmpl b/templates/explore/organizations.tmpl index 4b1ab1834..b977da4e4 100644 --- a/templates/explore/organizations.tmpl +++ b/templates/explore/organizations.tmpl @@ -18,7 +18,7 @@ {{.Website}} {{end}} - {{$.i18n.Tr "user.join_on"}} {{DateFmtShort .Created}} + {{$.i18n.Tr "user.join_on"}} {{.CreatedUnix.FormatShort}} diff --git a/templates/explore/repo_list.tmpl b/templates/explore/repo_list.tmpl index 4f264f483..06e3c0afd 100644 --- a/templates/explore/repo_list.tmpl +++ b/templates/explore/repo_list.tmpl @@ -17,7 +17,7 @@ {{if .DescriptionHTML}}

{{.DescriptionHTML}}

{{end}} -

{{$.i18n.Tr "org.repo_updated"}} {{TimeSince .Updated $.i18n.Lang}}

+

{{$.i18n.Tr "org.repo_updated"}} {{TimeSinceUnix .UpdatedUnix $.i18n.Lang}}

{{else}}
diff --git a/templates/explore/users.tmpl b/templates/explore/users.tmpl index 0bbbec2ed..32a36931c 100644 --- a/templates/explore/users.tmpl +++ b/templates/explore/users.tmpl @@ -18,7 +18,7 @@ {{.Email}} {{end}} - {{$.i18n.Tr "user.join_on"}} {{DateFmtShort .Created}} + {{$.i18n.Tr "user.join_on"}} {{.CreatedUnix.FormatShort}}
diff --git a/templates/repo/activity.tmpl b/templates/repo/activity.tmpl index eb761ff49..cd528582f 100644 --- a/templates/repo/activity.tmpl +++ b/templates/repo/activity.tmpl @@ -86,7 +86,7 @@ {{if not .IsTag}} {{.Title}} {{end}} - {{TimeSince .Created $.Lang}} + {{TimeSinceUnix .CreatedUnix $.Lang}}

{{end}} @@ -102,7 +102,7 @@

{{$.i18n.Tr "repo.activity.merged_prs_label"}}
#{{.Index}} {{.Issue.Title}} - {{TimeSince .Merged $.Lang}} + {{TimeSinceUnix .MergedUnix $.Lang}}

{{end}} @@ -118,7 +118,7 @@

{{$.i18n.Tr "repo.activity.opened_prs_label"}}
#{{.Index}} {{.Issue.Title}} - {{TimeSince .Issue.Created $.Lang}} + {{TimeSinceUnix .Issue.CreatedUnix $.Lang}}

{{end}} @@ -134,7 +134,7 @@

{{$.i18n.Tr "repo.activity.closed_issue_label"}}
#{{.Index}} {{.Title}} - {{TimeSince .Updated $.Lang}} + {{TimeSinceUnix .UpdatedUnix $.Lang}}

{{end}} @@ -150,7 +150,7 @@

{{$.i18n.Tr "repo.activity.new_issue_label"}}
#{{.Index}} {{.Title}} - {{TimeSince .Created $.Lang}} + {{TimeSinceUnix .CreatedUnix $.Lang}}

{{end}} @@ -174,7 +174,7 @@ {{else}} {{.Title}} {{end}} - {{TimeSince .Updated $.Lang}} + {{TimeSinceUnix .UpdatedUnix $.Lang}}

{{end}} diff --git a/templates/repo/branch/list.tmpl b/templates/repo/branch/list.tmpl index a1bbc1767..bc00d0d71 100644 --- a/templates/repo/branch/list.tmpl +++ b/templates/repo/branch/list.tmpl @@ -39,7 +39,7 @@ {{if .IsDeleted}} {{.Name}} -

{{$.i18n.Tr "repo.branch.deleted_by" .DeletedBranch.DeletedBy.Name}} {{TimeSince .DeletedBranch.Deleted $.i18n.Lang}}

+

{{$.i18n.Tr "repo.branch.deleted_by" .DeletedBranch.DeletedBy.Name}} {{TimeSinceUnix .DeletedBranch.DeletedUnix $.i18n.Lang}}

{{else}} {{.Name}}

{{$.i18n.Tr "org.repo_updated"}} {{TimeSince .Commit.Committer.When $.i18n.Lang}}

diff --git a/templates/repo/issue/list.tmpl b/templates/repo/issue/list.tmpl index bb6170a88..dec2881be 100644 --- a/templates/repo/issue/list.tmpl +++ b/templates/repo/issue/list.tmpl @@ -163,7 +163,7 @@
{{range .Issues}} - {{ $timeStr:= TimeSince .Created $.Lang }} + {{ $timeStr:= TimeSinceUnix .CreatedUnix $.Lang }}
  • diff --git a/templates/repo/issue/milestones.tmpl b/templates/repo/issue/milestones.tmpl index 3703301e1..de52bd42f 100644 --- a/templates/repo/issue/milestones.tmpl +++ b/templates/repo/issue/milestones.tmpl @@ -50,7 +50,7 @@
  • - {{ $closedDate:= TimeSince .ClosedDate $.Lang }} + {{ $closedDate:= TimeSinceUnix .ClosedDateUnix $.Lang }} {{if .IsClosed}} {{$.i18n.Tr "repo.milestones.closed" $closedDate|Str2html}} {{else}} diff --git a/templates/repo/issue/view_content.tmpl b/templates/repo/issue/view_content.tmpl index 795844d5d..4343aec9f 100644 --- a/templates/repo/issue/view_content.tmpl +++ b/templates/repo/issue/view_content.tmpl @@ -8,7 +8,7 @@ {{template "repo/issue/view_title" .}} {{end}} - {{ $createdStr:= TimeSince .Issue.Created $.Lang }} + {{ $createdStr:= TimeSinceUnix .Issue.CreatedUnix $.Lang }}
    diff --git a/templates/repo/issue/view_content/comments.tmpl b/templates/repo/issue/view_content/comments.tmpl index f073fe810..49a0216e8 100644 --- a/templates/repo/issue/view_content/comments.tmpl +++ b/templates/repo/issue/view_content/comments.tmpl @@ -1,5 +1,5 @@ {{range .Issue.Comments}} - {{ $createdStr:= TimeSince .Created $.Lang }} + {{ $createdStr:= TimeSinceUnix .CreatedUnix $.Lang }} {{if eq .Type 0}} diff --git a/templates/repo/issue/view_title.tmpl b/templates/repo/issue/view_title.tmpl index 4650ba4c8..d69f699ac 100644 --- a/templates/repo/issue/view_title.tmpl +++ b/templates/repo/issue/view_title.tmpl @@ -26,7 +26,7 @@ {{if .Issue.IsPull}} {{if .Issue.PullRequest.HasMerged}} - {{ $mergedStr:= TimeSince .Issue.PullRequest.Merged $.Lang }} + {{ $mergedStr:= TimeSinceUnix .Issue.PullRequest.MergedUnix $.Lang }} {{.Issue.PullRequest.Merger.Name}} {{$.i18n.Tr "repo.pulls.merged_title_desc" .NumCommits .HeadTarget .BaseTarget $mergedStr | Str2html}} {{else}} @@ -34,7 +34,7 @@ {{$.i18n.Tr "repo.pulls.title_desc" .NumCommits .HeadTarget .BaseTarget | Str2html}} {{end}} {{else}} - {{ $createdStr:= TimeSince .Issue.Created $.Lang }} + {{ $createdStr:= TimeSinceUnix .Issue.CreatedUnix $.Lang }} {{if gt .Issue.Poster.ID 0}} {{$.i18n.Tr "repo.issues.opened_by" $createdStr .Issue.Poster.HomeLink .Issue.Poster.Name | Safe}} diff --git a/templates/repo/release/list.tmpl b/templates/repo/release/list.tmpl index 2fed9ae58..0a3af5a84 100644 --- a/templates/repo/release/list.tmpl +++ b/templates/repo/release/list.tmpl @@ -18,7 +18,7 @@
  • {{if .IsTag}} - {{if .Created}}{{TimeSince .Created $.Lang}}{{end}} + {{if .CreatedUnix}}{{TimeSinceUnix .CreatedUnix $.Lang}}{{end}} {{else}} {{if .IsDraft}} {{$.i18n.Tr "repo.release.draft"}} @@ -55,7 +55,7 @@ {{.Publisher.Name}} - {{if .Created}}{{TimeSince .Created $.Lang}}{{end}} + {{if .CreatedUnix}}{{TimeSinceUnix .CreatedUnix $.Lang}}{{end}} {{$.i18n.Tr "repo.release.ahead" .NumCommitsBehind .Target | Str2html}}

    diff --git a/templates/repo/settings/deploy_keys.tmpl b/templates/repo/settings/deploy_keys.tmpl index caf9f29ce..3b22be532 100644 --- a/templates/repo/settings/deploy_keys.tmpl +++ b/templates/repo/settings/deploy_keys.tmpl @@ -31,7 +31,7 @@ {{.Fingerprint}}
    - {{$.i18n.Tr "settings.add_on"}} {{DateFmtShort .Created}} {{if .HasUsed}}{{$.i18n.Tr "settings.last_used"}} {{DateFmtShort .Updated}}{{else}}{{$.i18n.Tr "settings.no_activity"}}{{end}} + {{$.i18n.Tr "settings.add_on"}} {{.CreatedUnix.FormatShort}} {{if .HasUsed}}{{$.i18n.Tr "settings.last_used"}} {{.UpdatedUnix.FormatShort}}{{else}}{{$.i18n.Tr "settings.no_activity"}}{{end}}
  • diff --git a/templates/repo/settings/options.tmpl b/templates/repo/settings/options.tmpl index ee738cc9e..41a91ea26 100644 --- a/templates/repo/settings/options.tmpl +++ b/templates/repo/settings/options.tmpl @@ -76,7 +76,7 @@
    - {{.Mirror.Updated}} + {{.Mirror.UpdatedUnix.AsTime}}
    diff --git a/templates/repo/user_cards.tmpl b/templates/repo/user_cards.tmpl index c22caf257..5288d05ef 100644 --- a/templates/repo/user_cards.tmpl +++ b/templates/repo/user_cards.tmpl @@ -16,7 +16,7 @@ {{else if .Location}} {{.Location}} {{else}} - {{$.i18n.Tr "user.join_on"}} {{DateFmtShort .Created}} + {{$.i18n.Tr "user.join_on"}} {{.CreatedUnix.FormatShort}} {{end}}
    diff --git a/templates/repo/wiki/pages.tmpl b/templates/repo/wiki/pages.tmpl index 8437e9b6b..2829b6137 100644 --- a/templates/repo/wiki/pages.tmpl +++ b/templates/repo/wiki/pages.tmpl @@ -18,7 +18,7 @@ {{.Name}} - {{$timeSince := TimeSince .Updated $.Lang}} + {{$timeSince := TimeSinceUnix .UpdatedUnix $.Lang}} {{$.i18n.Tr "repo.wiki.last_updated" $timeSince | Safe}} {{end}} diff --git a/templates/user/dashboard/issues.tmpl b/templates/user/dashboard/issues.tmpl index 954b86821..cf2e10885 100644 --- a/templates/user/dashboard/issues.tmpl +++ b/templates/user/dashboard/issues.tmpl @@ -59,7 +59,7 @@
    {{range .Issues}} - {{ $timeStr:= TimeSince .Created $.Lang }} + {{ $timeStr:= TimeSinceUnix .CreatedUnix $.Lang }}
  • {{if not $.RepoID}}{{.Repo.FullName}}{{end}}#{{.Index}}
    {{.Title}} diff --git a/templates/user/profile.tmpl b/templates/user/profile.tmpl index 22a7f96ed..e89a4aa37 100644 --- a/templates/user/profile.tmpl +++ b/templates/user/profile.tmpl @@ -42,7 +42,7 @@
  • {{end}} {{end}} -
  • {{.i18n.Tr "user.join_on"}} {{DateFmtShort .Owner.Created}}
  • +
  • {{.i18n.Tr "user.join_on"}} {{.Owner.CreatedUnix.FormatShort}}
  • diff --git a/templates/user/settings/applications.tmpl b/templates/user/settings/applications.tmpl index d4d19dced..93b2f992d 100644 --- a/templates/user/settings/applications.tmpl +++ b/templates/user/settings/applications.tmpl @@ -25,7 +25,7 @@
    {{.Name}}
    - {{$.i18n.Tr "settings.add_on"}} {{DateFmtShort .Created}} {{if .HasUsed}}{{$.i18n.Tr "settings.last_used"}} {{DateFmtShort .Updated}}{{else}}{{$.i18n.Tr "settings.no_activity"}}{{end}} + {{$.i18n.Tr "settings.add_on"}} {{.CreatedUnix.FormatShort}} {{if .HasUsed}}{{$.i18n.Tr "settings.last_used"}} {{.UpdatedUnix.FormatShort}}{{else}}{{$.i18n.Tr "settings.no_activity"}}{{end}}
  • diff --git a/templates/user/settings/keys_gpg.tmpl b/templates/user/settings/keys_gpg.tmpl index 80b2b2752..3ae4249c8 100644 --- a/templates/user/settings/keys_gpg.tmpl +++ b/templates/user/settings/keys_gpg.tmpl @@ -24,9 +24,9 @@ {{$.i18n.Tr "settings.subkeys"}}: {{range .SubsKey}} {{.KeyID}} {{end}}
    - {{$.i18n.Tr "settings.add_on"}} {{DateFmtShort .Added}} + {{$.i18n.Tr "settings.add_on"}} {{.AddedUnix.FormatShort}} - - {{if not .Expired.IsZero }}{{$.i18n.Tr "settings.valid_until"}} {{DateFmtShort .Expired}}{{else}}{{$.i18n.Tr "settings.valid_forever"}}{{end}} + {{if .ExpiredUnix}}{{$.i18n.Tr "settings.valid_until"}} {{.ExpiredUnix.FormatShort}}{{else}}{{$.i18n.Tr "settings.valid_forever"}}{{end}}
    diff --git a/templates/user/settings/keys_ssh.tmpl b/templates/user/settings/keys_ssh.tmpl index bc93d3e4e..e954472ff 100644 --- a/templates/user/settings/keys_ssh.tmpl +++ b/templates/user/settings/keys_ssh.tmpl @@ -27,7 +27,7 @@ {{.Fingerprint}}
    - {{$.i18n.Tr "settings.add_on"}} {{DateFmtShort .Created}} {{if .HasUsed}}{{$.i18n.Tr "settings.last_used"}} {{DateFmtShort .Updated}}{{else}}{{$.i18n.Tr "settings.no_activity"}}{{end}} + {{$.i18n.Tr "settings.add_on"}} {{.CreatedUnix.FormatShort}} {{if .HasUsed}}{{$.i18n.Tr "settings.last_used"}} {{.UpdatedUnix.FormatShort}}{{else}}{{$.i18n.Tr "settings.no_activity"}}{{end}}