Display ui time with customize time location (#7792)
* display ui time with customize time location * fix lint * rename UILocation to DefaultUILocation * move time related functions to modules/timeutil * fix tests * fix tests * fix build * fix swagger
This commit is contained in:
		
							parent
							
								
									5a44be627c
								
							
						
					
					
						commit
						85202d4784
					
				
					 77 changed files with 770 additions and 662 deletions
				
			
		|  | @ -547,6 +547,9 @@ MAX_FILES = 5 | ||||||
| ; Special supported values are ANSIC, UnixDate, RubyDate, RFC822, RFC822Z, RFC850, RFC1123, RFC1123Z, RFC3339, RFC3339Nano, Kitchen, Stamp, StampMilli, StampMicro and StampNano | ; Special supported values are ANSIC, UnixDate, RubyDate, RFC822, RFC822Z, RFC850, RFC1123, RFC1123Z, RFC3339, RFC3339Nano, Kitchen, Stamp, StampMilli, StampMicro and StampNano | ||||||
| ; For more information about the format see http://golang.org/pkg/time/#pkg-constants | ; For more information about the format see http://golang.org/pkg/time/#pkg-constants | ||||||
| FORMAT = | FORMAT = | ||||||
|  | ; Location the UI time display i.e. Asia/Shanghai | ||||||
|  | ; Empty means server's location setting | ||||||
|  | DEFAULT_UI_LOCATION = | ||||||
| 
 | 
 | ||||||
| [log] | [log] | ||||||
| ROOT_PATH = | ROOT_PATH = | ||||||
|  |  | ||||||
|  | @ -503,8 +503,12 @@ Two special environment variables are passed to the render command: | ||||||
| - `GITEA_PREFIX_SRC`, which contains the current URL prefix in the `src` path tree. To be used as prefix for links. | - `GITEA_PREFIX_SRC`, which contains the current URL prefix in the `src` path tree. To be used as prefix for links. | ||||||
| - `GITEA_PREFIX_RAW`, which contains the current URL prefix in the `raw` path tree. To be used as prefix for image paths. | - `GITEA_PREFIX_RAW`, which contains the current URL prefix in the `raw` path tree. To be used as prefix for image paths. | ||||||
| 
 | 
 | ||||||
|  | ## Time (`time`) | ||||||
|  | - `FORMAT`: Time format to diplay on UI. i.e. RFC1123 or 2006-01-02 15:04:05 | ||||||
|  | - `DEFAULT_UI_LOCATION`: Default location of time on the UI, so that we can display correct user's time on UI. i.e. Shanghai/Asia | ||||||
|  | 
 | ||||||
| ## Other (`other`) | ## Other (`other`) | ||||||
| 
 | 
 | ||||||
| - `SHOW_FOOTER_BRANDING`: **false**: Show Gitea branding in the footer. | - `SHOW_FOOTER_BRANDING`: **false**: Show Gitea branding in the footer. | ||||||
| - `SHOW_FOOTER_VERSION`: **true**: Show Gitea version information in the footer. | - `SHOW_FOOTER_VERSION`: **true**: Show Gitea version information in the footer. | ||||||
| - `SHOW_FOOTER_TEMPLATE_LOAD_TIME`: **true**: Show time of template execution in the footer. | - `SHOW_FOOTER_TEMPLATE_LOAD_TIME`: **true**: Show time of template execution in the footer. | ||||||
|  | @ -237,7 +237,9 @@ IS_INPUT_FILE = false | ||||||
| - RENDER_COMMAND: 工具的命令行命令及参数。 | - RENDER_COMMAND: 工具的命令行命令及参数。 | ||||||
| - IS_INPUT_FILE: 输入方式是最后一个参数为文件路径还是从标准输入读取。 | - IS_INPUT_FILE: 输入方式是最后一个参数为文件路径还是从标准输入读取。 | ||||||
| 
 | 
 | ||||||
| 
 | ## Time (`time`) | ||||||
|  | - `FORMAT`: 显示在界面上的时间格式。比如: RFC1123 或者 2006-01-02 15:04:05 | ||||||
|  | - `DEFAULT_UI_LOCATION`: 默认显示在界面上的时区,默认为本地时区。比如: Asia/Shanghai | ||||||
| 
 | 
 | ||||||
| ## Other (`other`) | ## Other (`other`) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -20,7 +20,7 @@ import ( | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	api "code.gitea.io/gitea/modules/structs" | 	api "code.gitea.io/gitea/modules/structs" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 
 | 
 | ||||||
| 	"github.com/Unknwon/com" | 	"github.com/Unknwon/com" | ||||||
| 	"xorm.io/builder" | 	"xorm.io/builder" | ||||||
|  | @ -91,9 +91,9 @@ type Action struct { | ||||||
| 	Comment     *Comment    `xorm:"-"` | 	Comment     *Comment    `xorm:"-"` | ||||||
| 	IsDeleted   bool        `xorm:"INDEX NOT NULL DEFAULT false"` | 	IsDeleted   bool        `xorm:"INDEX NOT NULL DEFAULT false"` | ||||||
| 	RefName     string | 	RefName     string | ||||||
| 	IsPrivate   bool           `xorm:"INDEX NOT NULL DEFAULT false"` | 	IsPrivate   bool               `xorm:"INDEX NOT NULL DEFAULT false"` | ||||||
| 	Content     string         `xorm:"TEXT"` | 	Content     string             `xorm:"TEXT"` | ||||||
| 	CreatedUnix util.TimeStamp `xorm:"INDEX created"` | 	CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // GetOpType gets the ActionType of this action.
 | // GetOpType gets the ActionType of this action.
 | ||||||
|  |  | ||||||
|  | @ -9,7 +9,7 @@ import ( | ||||||
| 	"os" | 	"os" | ||||||
| 
 | 
 | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 
 | 
 | ||||||
| 	"github.com/Unknwon/com" | 	"github.com/Unknwon/com" | ||||||
| ) | ) | ||||||
|  | @ -26,8 +26,8 @@ const ( | ||||||
| type Notice struct { | type Notice struct { | ||||||
| 	ID          int64 `xorm:"pk autoincr"` | 	ID          int64 `xorm:"pk autoincr"` | ||||||
| 	Type        NoticeType | 	Type        NoticeType | ||||||
| 	Description string         `xorm:"TEXT"` | 	Description string             `xorm:"TEXT"` | ||||||
| 	CreatedUnix util.TimeStamp `xorm:"INDEX created"` | 	CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // TrStr returns a translation format string.
 | // TrStr returns a translation format string.
 | ||||||
|  |  | ||||||
|  | @ -12,7 +12,7 @@ import ( | ||||||
| 
 | 
 | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	api "code.gitea.io/gitea/modules/structs" | 	api "code.gitea.io/gitea/modules/structs" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 
 | 
 | ||||||
| 	"github.com/go-xorm/xorm" | 	"github.com/go-xorm/xorm" | ||||||
| 	gouuid "github.com/satori/go.uuid" | 	gouuid "github.com/satori/go.uuid" | ||||||
|  | @ -27,9 +27,9 @@ type Attachment struct { | ||||||
| 	UploaderID    int64  `xorm:"INDEX DEFAULT 0"` // Notice: will be zero before this column added
 | 	UploaderID    int64  `xorm:"INDEX DEFAULT 0"` // Notice: will be zero before this column added
 | ||||||
| 	CommentID     int64 | 	CommentID     int64 | ||||||
| 	Name          string | 	Name          string | ||||||
| 	DownloadCount int64          `xorm:"DEFAULT 0"` | 	DownloadCount int64              `xorm:"DEFAULT 0"` | ||||||
| 	Size          int64          `xorm:"DEFAULT 0"` | 	Size          int64              `xorm:"DEFAULT 0"` | ||||||
| 	CreatedUnix   util.TimeStamp `xorm:"created"` | 	CreatedUnix   timeutil.TimeStamp `xorm:"created"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // IncreaseDownloadCount is update download count + 1
 | // IncreaseDownloadCount is update download count + 1
 | ||||||
|  |  | ||||||
|  | @ -11,6 +11,7 @@ import ( | ||||||
| 	"code.gitea.io/gitea/modules/base" | 	"code.gitea.io/gitea/modules/base" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
|  | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/util" | ||||||
| 
 | 
 | ||||||
| 	"github.com/Unknwon/com" | 	"github.com/Unknwon/com" | ||||||
|  | @ -30,16 +31,16 @@ type ProtectedBranch struct { | ||||||
| 	BranchName                string `xorm:"UNIQUE(s)"` | 	BranchName                string `xorm:"UNIQUE(s)"` | ||||||
| 	CanPush                   bool   `xorm:"NOT NULL DEFAULT false"` | 	CanPush                   bool   `xorm:"NOT NULL DEFAULT false"` | ||||||
| 	EnableWhitelist           bool | 	EnableWhitelist           bool | ||||||
| 	WhitelistUserIDs          []int64        `xorm:"JSON TEXT"` | 	WhitelistUserIDs          []int64            `xorm:"JSON TEXT"` | ||||||
| 	WhitelistTeamIDs          []int64        `xorm:"JSON TEXT"` | 	WhitelistTeamIDs          []int64            `xorm:"JSON TEXT"` | ||||||
| 	EnableMergeWhitelist      bool           `xorm:"NOT NULL DEFAULT false"` | 	EnableMergeWhitelist      bool               `xorm:"NOT NULL DEFAULT false"` | ||||||
| 	MergeWhitelistUserIDs     []int64        `xorm:"JSON TEXT"` | 	MergeWhitelistUserIDs     []int64            `xorm:"JSON TEXT"` | ||||||
| 	MergeWhitelistTeamIDs     []int64        `xorm:"JSON TEXT"` | 	MergeWhitelistTeamIDs     []int64            `xorm:"JSON TEXT"` | ||||||
| 	ApprovalsWhitelistUserIDs []int64        `xorm:"JSON TEXT"` | 	ApprovalsWhitelistUserIDs []int64            `xorm:"JSON TEXT"` | ||||||
| 	ApprovalsWhitelistTeamIDs []int64        `xorm:"JSON TEXT"` | 	ApprovalsWhitelistTeamIDs []int64            `xorm:"JSON TEXT"` | ||||||
| 	RequiredApprovals         int64          `xorm:"NOT NULL DEFAULT 0"` | 	RequiredApprovals         int64              `xorm:"NOT NULL DEFAULT 0"` | ||||||
| 	CreatedUnix               util.TimeStamp `xorm:"created"` | 	CreatedUnix               timeutil.TimeStamp `xorm:"created"` | ||||||
| 	UpdatedUnix               util.TimeStamp `xorm:"updated"` | 	UpdatedUnix               timeutil.TimeStamp `xorm:"updated"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // IsProtected returns if the branch is protected
 | // IsProtected returns if the branch is protected
 | ||||||
|  | @ -374,13 +375,13 @@ func (repo *Repository) DeleteProtectedBranch(id int64) (err error) { | ||||||
| 
 | 
 | ||||||
| // DeletedBranch struct
 | // DeletedBranch struct
 | ||||||
| type DeletedBranch struct { | type DeletedBranch struct { | ||||||
| 	ID          int64          `xorm:"pk autoincr"` | 	ID          int64              `xorm:"pk autoincr"` | ||||||
| 	RepoID      int64          `xorm:"UNIQUE(s) INDEX NOT NULL"` | 	RepoID      int64              `xorm:"UNIQUE(s) INDEX NOT NULL"` | ||||||
| 	Name        string         `xorm:"UNIQUE(s) NOT NULL"` | 	Name        string             `xorm:"UNIQUE(s) NOT NULL"` | ||||||
| 	Commit      string         `xorm:"UNIQUE(s) NOT NULL"` | 	Commit      string             `xorm:"UNIQUE(s) NOT NULL"` | ||||||
| 	DeletedByID int64          `xorm:"INDEX"` | 	DeletedByID int64              `xorm:"INDEX"` | ||||||
| 	DeletedBy   *User          `xorm:"-"` | 	DeletedBy   *User              `xorm:"-"` | ||||||
| 	DeletedUnix util.TimeStamp `xorm:"INDEX created"` | 	DeletedUnix timeutil.TimeStamp `xorm:"INDEX created"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // AddDeletedBranch adds a deleted branch to the database
 | // AddDeletedBranch adds a deleted branch to the database
 | ||||||
|  |  | ||||||
|  | @ -13,7 +13,7 @@ import ( | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	api "code.gitea.io/gitea/modules/structs" | 	api "code.gitea.io/gitea/modules/structs" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 
 | 
 | ||||||
| 	"github.com/go-xorm/xorm" | 	"github.com/go-xorm/xorm" | ||||||
| ) | ) | ||||||
|  | @ -66,8 +66,8 @@ type CommitStatus struct { | ||||||
| 	Creator     *User             `xorm:"-"` | 	Creator     *User             `xorm:"-"` | ||||||
| 	CreatorID   int64 | 	CreatorID   int64 | ||||||
| 
 | 
 | ||||||
| 	CreatedUnix util.TimeStamp `xorm:"INDEX created"` | 	CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | ||||||
| 	UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` | 	UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (status *CommitStatus) loadRepo(e Engine) (err error) { | func (status *CommitStatus) loadRepo(e Engine) (err error) { | ||||||
|  |  | ||||||
|  | @ -17,7 +17,7 @@ import ( | ||||||
| 
 | 
 | ||||||
| 	"code.gitea.io/gitea/modules/git" | 	"code.gitea.io/gitea/modules/git" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 
 | 
 | ||||||
| 	"github.com/go-xorm/xorm" | 	"github.com/go-xorm/xorm" | ||||||
| 	"github.com/keybase/go-crypto/openpgp" | 	"github.com/keybase/go-crypto/openpgp" | ||||||
|  | @ -27,14 +27,14 @@ import ( | ||||||
| 
 | 
 | ||||||
| // GPGKey represents a GPG key.
 | // GPGKey represents a GPG key.
 | ||||||
| type GPGKey struct { | type GPGKey struct { | ||||||
| 	ID                int64          `xorm:"pk autoincr"` | 	ID                int64              `xorm:"pk autoincr"` | ||||||
| 	OwnerID           int64          `xorm:"INDEX NOT NULL"` | 	OwnerID           int64              `xorm:"INDEX NOT NULL"` | ||||||
| 	KeyID             string         `xorm:"INDEX CHAR(16) NOT NULL"` | 	KeyID             string             `xorm:"INDEX CHAR(16) NOT NULL"` | ||||||
| 	PrimaryKeyID      string         `xorm:"CHAR(16)"` | 	PrimaryKeyID      string             `xorm:"CHAR(16)"` | ||||||
| 	Content           string         `xorm:"TEXT NOT NULL"` | 	Content           string             `xorm:"TEXT NOT NULL"` | ||||||
| 	CreatedUnix       util.TimeStamp `xorm:"created"` | 	CreatedUnix       timeutil.TimeStamp `xorm:"created"` | ||||||
| 	ExpiredUnix       util.TimeStamp | 	ExpiredUnix       timeutil.TimeStamp | ||||||
| 	AddedUnix         util.TimeStamp | 	AddedUnix         timeutil.TimeStamp | ||||||
| 	SubsKey           []*GPGKey `xorm:"-"` | 	SubsKey           []*GPGKey `xorm:"-"` | ||||||
| 	Emails            []*EmailAddress | 	Emails            []*EmailAddress | ||||||
| 	CanSign           bool | 	CanSign           bool | ||||||
|  | @ -51,7 +51,7 @@ type GPGKeyImport struct { | ||||||
| 
 | 
 | ||||||
| // BeforeInsert will be invoked by XORM before inserting a record
 | // BeforeInsert will be invoked by XORM before inserting a record
 | ||||||
| func (key *GPGKey) BeforeInsert() { | func (key *GPGKey) BeforeInsert() { | ||||||
| 	key.AddedUnix = util.TimeStampNow() | 	key.AddedUnix = timeutil.TimeStampNow() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // AfterLoad is invoked from XORM after setting the values of all fields of this object.
 | // AfterLoad is invoked from XORM after setting the values of all fields of this object.
 | ||||||
|  | @ -223,8 +223,8 @@ func parseSubGPGKey(ownerID int64, primaryID string, pubkey *packet.PublicKey, e | ||||||
| 		KeyID:             pubkey.KeyIdString(), | 		KeyID:             pubkey.KeyIdString(), | ||||||
| 		PrimaryKeyID:      primaryID, | 		PrimaryKeyID:      primaryID, | ||||||
| 		Content:           content, | 		Content:           content, | ||||||
| 		CreatedUnix:       util.TimeStamp(pubkey.CreationTime.Unix()), | 		CreatedUnix:       timeutil.TimeStamp(pubkey.CreationTime.Unix()), | ||||||
| 		ExpiredUnix:       util.TimeStamp(expiry.Unix()), | 		ExpiredUnix:       timeutil.TimeStamp(expiry.Unix()), | ||||||
| 		CanSign:           pubkey.CanSign(), | 		CanSign:           pubkey.CanSign(), | ||||||
| 		CanEncryptComms:   pubkey.PubKeyAlgo.CanEncrypt(), | 		CanEncryptComms:   pubkey.PubKeyAlgo.CanEncrypt(), | ||||||
| 		CanEncryptStorage: pubkey.PubKeyAlgo.CanEncrypt(), | 		CanEncryptStorage: pubkey.PubKeyAlgo.CanEncrypt(), | ||||||
|  | @ -301,8 +301,8 @@ func parseGPGKey(ownerID int64, e *openpgp.Entity) (*GPGKey, error) { | ||||||
| 		KeyID:             pubkey.KeyIdString(), | 		KeyID:             pubkey.KeyIdString(), | ||||||
| 		PrimaryKeyID:      "", | 		PrimaryKeyID:      "", | ||||||
| 		Content:           content, | 		Content:           content, | ||||||
| 		CreatedUnix:       util.TimeStamp(pubkey.CreationTime.Unix()), | 		CreatedUnix:       timeutil.TimeStamp(pubkey.CreationTime.Unix()), | ||||||
| 		ExpiredUnix:       util.TimeStamp(expiry.Unix()), | 		ExpiredUnix:       timeutil.TimeStamp(expiry.Unix()), | ||||||
| 		Emails:            emails, | 		Emails:            emails, | ||||||
| 		SubsKey:           subkeys, | 		SubsKey:           subkeys, | ||||||
| 		CanSign:           pubkey.CanSign(), | 		CanSign:           pubkey.CanSign(), | ||||||
|  |  | ||||||
|  | @ -8,7 +8,7 @@ import ( | ||||||
| 	"testing" | 	"testing" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 
 | 
 | ||||||
| 	"github.com/stretchr/testify/assert" | 	"github.com/stretchr/testify/assert" | ||||||
| ) | ) | ||||||
|  | @ -112,7 +112,7 @@ MkM/fdpyc2hY7Dl/+qFmN5MG5yGmMpQcX+RNNR222ibNC1D3wg== | ||||||
| 	key := &GPGKey{ | 	key := &GPGKey{ | ||||||
| 		KeyID:             pubkey.KeyIdString(), | 		KeyID:             pubkey.KeyIdString(), | ||||||
| 		Content:           content, | 		Content:           content, | ||||||
| 		CreatedUnix:       util.TimeStamp(pubkey.CreationTime.Unix()), | 		CreatedUnix:       timeutil.TimeStamp(pubkey.CreationTime.Unix()), | ||||||
| 		CanSign:           pubkey.CanSign(), | 		CanSign:           pubkey.CanSign(), | ||||||
| 		CanEncryptComms:   pubkey.PubKeyAlgo.CanEncrypt(), | 		CanEncryptComms:   pubkey.PubKeyAlgo.CanEncrypt(), | ||||||
| 		CanEncryptStorage: pubkey.PubKeyAlgo.CanEncrypt(), | 		CanEncryptStorage: pubkey.PubKeyAlgo.CanEncrypt(), | ||||||
|  | @ -122,7 +122,7 @@ MkM/fdpyc2hY7Dl/+qFmN5MG5yGmMpQcX+RNNR222ibNC1D3wg== | ||||||
| 	cannotsignkey := &GPGKey{ | 	cannotsignkey := &GPGKey{ | ||||||
| 		KeyID:             pubkey.KeyIdString(), | 		KeyID:             pubkey.KeyIdString(), | ||||||
| 		Content:           content, | 		Content:           content, | ||||||
| 		CreatedUnix:       util.TimeStamp(pubkey.CreationTime.Unix()), | 		CreatedUnix:       timeutil.TimeStamp(pubkey.CreationTime.Unix()), | ||||||
| 		CanSign:           false, | 		CanSign:           false, | ||||||
| 		CanEncryptComms:   false, | 		CanEncryptComms:   false, | ||||||
| 		CanEncryptStorage: false, | 		CanEncryptStorage: false, | ||||||
|  |  | ||||||
|  | @ -16,6 +16,7 @@ import ( | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	api "code.gitea.io/gitea/modules/structs" | 	api "code.gitea.io/gitea/modules/structs" | ||||||
|  | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/util" | ||||||
| 
 | 
 | ||||||
| 	"github.com/Unknwon/com" | 	"github.com/Unknwon/com" | ||||||
|  | @ -49,11 +50,11 @@ type Issue struct { | ||||||
| 	NumComments      int | 	NumComments      int | ||||||
| 	Ref              string | 	Ref              string | ||||||
| 
 | 
 | ||||||
| 	DeadlineUnix util.TimeStamp `xorm:"INDEX"` | 	DeadlineUnix timeutil.TimeStamp `xorm:"INDEX"` | ||||||
| 
 | 
 | ||||||
| 	CreatedUnix util.TimeStamp `xorm:"INDEX created"` | 	CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | ||||||
| 	UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` | 	UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | ||||||
| 	ClosedUnix  util.TimeStamp `xorm:"INDEX"` | 	ClosedUnix  timeutil.TimeStamp `xorm:"INDEX"` | ||||||
| 
 | 
 | ||||||
| 	Attachments      []*Attachment `xorm:"-"` | 	Attachments      []*Attachment `xorm:"-"` | ||||||
| 	Comments         []*Comment    `xorm:"-"` | 	Comments         []*Comment    `xorm:"-"` | ||||||
|  | @ -90,7 +91,7 @@ func (issue *Issue) loadTotalTimes(e Engine) (err error) { | ||||||
| 
 | 
 | ||||||
| // IsOverdue checks if the issue is overdue
 | // IsOverdue checks if the issue is overdue
 | ||||||
| func (issue *Issue) IsOverdue() bool { | func (issue *Issue) IsOverdue() bool { | ||||||
| 	return util.TimeStampNow() >= issue.DeadlineUnix | 	return timeutil.TimeStampNow() >= issue.DeadlineUnix | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // LoadRepo loads issue's repository
 | // LoadRepo loads issue's repository
 | ||||||
|  | @ -744,7 +745,7 @@ func (issue *Issue) changeStatus(e *xorm.Session, doer *User, isClosed bool) (er | ||||||
| 
 | 
 | ||||||
| 	issue.IsClosed = isClosed | 	issue.IsClosed = isClosed | ||||||
| 	if isClosed { | 	if isClosed { | ||||||
| 		issue.ClosedUnix = util.TimeStampNow() | 		issue.ClosedUnix = timeutil.TimeStampNow() | ||||||
| 	} else { | 	} else { | ||||||
| 		issue.ClosedUnix = 0 | 		issue.ClosedUnix = 0 | ||||||
| 	} | 	} | ||||||
|  | @ -991,7 +992,7 @@ func (issue *Issue) GetTasksDone() int { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // GetLastEventTimestamp returns the last user visible event timestamp, either the creation of this issue or the close.
 | // GetLastEventTimestamp returns the last user visible event timestamp, either the creation of this issue or the close.
 | ||||||
| func (issue *Issue) GetLastEventTimestamp() util.TimeStamp { | func (issue *Issue) GetLastEventTimestamp() timeutil.TimeStamp { | ||||||
| 	if issue.IsClosed { | 	if issue.IsClosed { | ||||||
| 		return issue.ClosedUnix | 		return issue.ClosedUnix | ||||||
| 	} | 	} | ||||||
|  | @ -1794,7 +1795,7 @@ func UpdateIssue(issue *Issue) error { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // UpdateIssueDeadline updates an issue deadline and adds comments. Setting a deadline to 0 means deleting it.
 | // UpdateIssueDeadline updates an issue deadline and adds comments. Setting a deadline to 0 means deleting it.
 | ||||||
| func UpdateIssueDeadline(issue *Issue, deadlineUnix util.TimeStamp, doer *User) (err error) { | func UpdateIssueDeadline(issue *Issue, deadlineUnix timeutil.TimeStamp, doer *User) (err error) { | ||||||
| 
 | 
 | ||||||
| 	// if the deadline hasn't changed do nothing
 | 	// if the deadline hasn't changed do nothing
 | ||||||
| 	if issue.DeadlineUnix == deadlineUnix { | 	if issue.DeadlineUnix == deadlineUnix { | ||||||
|  |  | ||||||
|  | @ -12,17 +12,16 @@ import ( | ||||||
| 	"strings" | 	"strings" | ||||||
| 
 | 
 | ||||||
| 	"code.gitea.io/gitea/modules/git" | 	"code.gitea.io/gitea/modules/git" | ||||||
|  | 	"code.gitea.io/gitea/modules/log" | ||||||
|  | 	"code.gitea.io/gitea/modules/markup" | ||||||
| 	"code.gitea.io/gitea/modules/markup/markdown" | 	"code.gitea.io/gitea/modules/markup/markdown" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
|  | 	api "code.gitea.io/gitea/modules/structs" | ||||||
|  | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
|  | 
 | ||||||
| 	"github.com/Unknwon/com" | 	"github.com/Unknwon/com" | ||||||
| 	"github.com/go-xorm/xorm" | 	"github.com/go-xorm/xorm" | ||||||
| 	"xorm.io/builder" | 	"xorm.io/builder" | ||||||
| 
 |  | ||||||
| 	api "code.gitea.io/gitea/modules/structs" |  | ||||||
| 
 |  | ||||||
| 	"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.
 | // CommentType defines whether a comment is just a simple comment, an action (like close) or a reference.
 | ||||||
|  | @ -130,8 +129,8 @@ type Comment struct { | ||||||
| 	// Path represents the 4 lines of code cemented by this comment
 | 	// Path represents the 4 lines of code cemented by this comment
 | ||||||
| 	Patch string `xorm:"TEXT"` | 	Patch string `xorm:"TEXT"` | ||||||
| 
 | 
 | ||||||
| 	CreatedUnix util.TimeStamp `xorm:"INDEX created"` | 	CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | ||||||
| 	UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` | 	UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | ||||||
| 
 | 
 | ||||||
| 	// Reference issue in commit message
 | 	// Reference issue in commit message
 | ||||||
| 	CommitSHA string `xorm:"VARCHAR(40)"` | 	CommitSHA string `xorm:"VARCHAR(40)"` | ||||||
|  | @ -711,7 +710,7 @@ func createAssigneeComment(e *xorm.Session, doer *User, repo *Repository, issue | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func createDeadlineComment(e *xorm.Session, doer *User, issue *Issue, newDeadlineUnix util.TimeStamp) (*Comment, error) { | func createDeadlineComment(e *xorm.Session, doer *User, issue *Issue, newDeadlineUnix timeutil.TimeStamp) (*Comment, error) { | ||||||
| 
 | 
 | ||||||
| 	var content string | 	var content string | ||||||
| 	var commentType CommentType | 	var commentType CommentType | ||||||
|  |  | ||||||
|  | @ -7,17 +7,17 @@ package models | ||||||
| import ( | import ( | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // IssueDependency represents an issue dependency
 | // IssueDependency represents an issue dependency
 | ||||||
| type IssueDependency struct { | type IssueDependency struct { | ||||||
| 	ID           int64          `xorm:"pk autoincr"` | 	ID           int64              `xorm:"pk autoincr"` | ||||||
| 	UserID       int64          `xorm:"NOT NULL"` | 	UserID       int64              `xorm:"NOT NULL"` | ||||||
| 	IssueID      int64          `xorm:"UNIQUE(issue_dependency) NOT NULL"` | 	IssueID      int64              `xorm:"UNIQUE(issue_dependency) NOT NULL"` | ||||||
| 	DependencyID int64          `xorm:"UNIQUE(issue_dependency) NOT NULL"` | 	DependencyID int64              `xorm:"UNIQUE(issue_dependency) NOT NULL"` | ||||||
| 	CreatedUnix  util.TimeStamp `xorm:"created"` | 	CreatedUnix  timeutil.TimeStamp `xorm:"created"` | ||||||
| 	UpdatedUnix  util.TimeStamp `xorm:"updated"` | 	UpdatedUnix  timeutil.TimeStamp `xorm:"updated"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // DependencyType Defines Dependency Type Constants
 | // DependencyType Defines Dependency Type Constants
 | ||||||
|  |  | ||||||
|  | @ -10,7 +10,8 @@ import ( | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	api "code.gitea.io/gitea/modules/structs" | 	api "code.gitea.io/gitea/modules/structs" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
|  | 
 | ||||||
| 	"github.com/go-xorm/xorm" | 	"github.com/go-xorm/xorm" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -29,8 +30,8 @@ type Milestone struct { | ||||||
| 	IsOverdue       bool `xorm:"-"` | 	IsOverdue       bool `xorm:"-"` | ||||||
| 
 | 
 | ||||||
| 	DeadlineString string `xorm:"-"` | 	DeadlineString string `xorm:"-"` | ||||||
| 	DeadlineUnix   util.TimeStamp | 	DeadlineUnix   timeutil.TimeStamp | ||||||
| 	ClosedDateUnix util.TimeStamp | 	ClosedDateUnix timeutil.TimeStamp | ||||||
| 
 | 
 | ||||||
| 	TotalTrackedTime int64 `xorm:"-"` | 	TotalTrackedTime int64 `xorm:"-"` | ||||||
| } | } | ||||||
|  | @ -53,7 +54,7 @@ func (m *Milestone) AfterLoad() { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	m.DeadlineString = m.DeadlineUnix.Format("2006-01-02") | 	m.DeadlineString = m.DeadlineUnix.Format("2006-01-02") | ||||||
| 	if util.TimeStampNow() >= m.DeadlineUnix { | 	if timeutil.TimeStampNow() >= m.DeadlineUnix { | ||||||
| 		m.IsOverdue = true | 		m.IsOverdue = true | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -10,7 +10,7 @@ import ( | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	api "code.gitea.io/gitea/modules/structs" | 	api "code.gitea.io/gitea/modules/structs" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 
 | 
 | ||||||
| 	"github.com/stretchr/testify/assert" | 	"github.com/stretchr/testify/assert" | ||||||
| ) | ) | ||||||
|  | @ -29,7 +29,7 @@ func TestMilestone_APIFormat(t *testing.T) { | ||||||
| 		IsClosed:        false, | 		IsClosed:        false, | ||||||
| 		NumOpenIssues:   5, | 		NumOpenIssues:   5, | ||||||
| 		NumClosedIssues: 6, | 		NumClosedIssues: 6, | ||||||
| 		DeadlineUnix:    util.TimeStamp(time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC).Unix()), | 		DeadlineUnix:    timeutil.TimeStamp(time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC).Unix()), | ||||||
| 	} | 	} | ||||||
| 	assert.Equal(t, api.Milestone{ | 	assert.Equal(t, api.Milestone{ | ||||||
| 		ID:           milestone.ID, | 		ID:           milestone.ID, | ||||||
|  | @ -237,7 +237,7 @@ func TestChangeMilestoneIssueStats(t *testing.T) { | ||||||
| 		"is_closed=0").(*Issue) | 		"is_closed=0").(*Issue) | ||||||
| 
 | 
 | ||||||
| 	issue.IsClosed = true | 	issue.IsClosed = true | ||||||
| 	issue.ClosedUnix = util.TimeStampNow() | 	issue.ClosedUnix = timeutil.TimeStampNow() | ||||||
| 	_, err := x.Cols("is_closed", "closed_unix").Update(issue) | 	_, err := x.Cols("is_closed", "closed_unix").Update(issue) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.NoError(t, changeMilestoneIssueStats(x.NewSession(), issue)) | 	assert.NoError(t, changeMilestoneIssueStats(x.NewSession(), issue)) | ||||||
|  |  | ||||||
|  | @ -9,7 +9,7 @@ import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 
 | 
 | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 
 | 
 | ||||||
| 	"github.com/go-xorm/xorm" | 	"github.com/go-xorm/xorm" | ||||||
| 	"xorm.io/builder" | 	"xorm.io/builder" | ||||||
|  | @ -17,13 +17,13 @@ import ( | ||||||
| 
 | 
 | ||||||
| // Reaction represents a reactions on issues and comments.
 | // Reaction represents a reactions on issues and comments.
 | ||||||
| type Reaction struct { | type Reaction struct { | ||||||
| 	ID          int64          `xorm:"pk autoincr"` | 	ID          int64              `xorm:"pk autoincr"` | ||||||
| 	Type        string         `xorm:"INDEX UNIQUE(s) NOT NULL"` | 	Type        string             `xorm:"INDEX UNIQUE(s) NOT NULL"` | ||||||
| 	IssueID     int64          `xorm:"INDEX UNIQUE(s) NOT NULL"` | 	IssueID     int64              `xorm:"INDEX UNIQUE(s) NOT NULL"` | ||||||
| 	CommentID   int64          `xorm:"INDEX UNIQUE(s)"` | 	CommentID   int64              `xorm:"INDEX UNIQUE(s)"` | ||||||
| 	UserID      int64          `xorm:"INDEX UNIQUE(s) NOT NULL"` | 	UserID      int64              `xorm:"INDEX UNIQUE(s) NOT NULL"` | ||||||
| 	User        *User          `xorm:"-"` | 	User        *User              `xorm:"-"` | ||||||
| 	CreatedUnix util.TimeStamp `xorm:"INDEX created"` | 	CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // FindReactionsOptions describes the conditions to Find reactions
 | // FindReactionsOptions describes the conditions to Find reactions
 | ||||||
|  |  | ||||||
|  | @ -8,15 +8,15 @@ import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // Stopwatch represents a stopwatch for time tracking.
 | // Stopwatch represents a stopwatch for time tracking.
 | ||||||
| type Stopwatch struct { | type Stopwatch struct { | ||||||
| 	ID          int64          `xorm:"pk autoincr"` | 	ID          int64              `xorm:"pk autoincr"` | ||||||
| 	IssueID     int64          `xorm:"INDEX"` | 	IssueID     int64              `xorm:"INDEX"` | ||||||
| 	UserID      int64          `xorm:"INDEX"` | 	UserID      int64              `xorm:"INDEX"` | ||||||
| 	CreatedUnix util.TimeStamp `xorm:"created"` | 	CreatedUnix timeutil.TimeStamp `xorm:"created"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func getStopwatch(e Engine, userID, issueID int64) (sw *Stopwatch, exists bool, err error) { | func getStopwatch(e Engine, userID, issueID int64) (sw *Stopwatch, exists bool, err error) { | ||||||
|  |  | ||||||
|  | @ -3,7 +3,7 @@ package models | ||||||
| import ( | import ( | ||||||
| 	"testing" | 	"testing" | ||||||
| 
 | 
 | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 
 | 
 | ||||||
| 	"github.com/stretchr/testify/assert" | 	"github.com/stretchr/testify/assert" | ||||||
| ) | ) | ||||||
|  | @ -63,7 +63,7 @@ func TestCreateOrStopIssueStopwatch(t *testing.T) { | ||||||
| 
 | 
 | ||||||
| 	assert.NoError(t, CreateOrStopIssueStopwatch(user3, issue1)) | 	assert.NoError(t, CreateOrStopIssueStopwatch(user3, issue1)) | ||||||
| 	sw := AssertExistsAndLoadBean(t, &Stopwatch{UserID: 3, IssueID: 1}).(*Stopwatch) | 	sw := AssertExistsAndLoadBean(t, &Stopwatch{UserID: 3, IssueID: 1}).(*Stopwatch) | ||||||
| 	assert.Equal(t, true, sw.CreatedUnix <= util.TimeStampNow()) | 	assert.Equal(t, true, sw.CreatedUnix <= timeutil.TimeStampNow()) | ||||||
| 
 | 
 | ||||||
| 	assert.NoError(t, CreateOrStopIssueStopwatch(user2, issue2)) | 	assert.NoError(t, CreateOrStopIssueStopwatch(user2, issue2)) | ||||||
| 	AssertNotExistsBean(t, &Stopwatch{UserID: 2, IssueID: 2}) | 	AssertNotExistsBean(t, &Stopwatch{UserID: 2, IssueID: 2}) | ||||||
|  |  | ||||||
|  | @ -26,7 +26,7 @@ type TrackedTime struct { | ||||||
| 
 | 
 | ||||||
| // AfterLoad is invoked from XORM after setting the values of all fields of this object.
 | // AfterLoad is invoked from XORM after setting the values of all fields of this object.
 | ||||||
| func (t *TrackedTime) AfterLoad() { | func (t *TrackedTime) AfterLoad() { | ||||||
| 	t.Created = time.Unix(t.CreatedUnix, 0).In(setting.UILocation) | 	t.Created = time.Unix(t.CreatedUnix, 0).In(setting.DefaultUILocation) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // APIFormat converts TrackedTime to API format
 | // APIFormat converts TrackedTime to API format
 | ||||||
|  |  | ||||||
|  | @ -4,16 +4,16 @@ | ||||||
| 
 | 
 | ||||||
| package models | package models | ||||||
| 
 | 
 | ||||||
| import "code.gitea.io/gitea/modules/util" | import "code.gitea.io/gitea/modules/timeutil" | ||||||
| 
 | 
 | ||||||
| // IssueWatch is connection request for receiving issue notification.
 | // IssueWatch is connection request for receiving issue notification.
 | ||||||
| type IssueWatch struct { | type IssueWatch struct { | ||||||
| 	ID          int64          `xorm:"pk autoincr"` | 	ID          int64              `xorm:"pk autoincr"` | ||||||
| 	UserID      int64          `xorm:"UNIQUE(watch) NOT NULL"` | 	UserID      int64              `xorm:"UNIQUE(watch) NOT NULL"` | ||||||
| 	IssueID     int64          `xorm:"UNIQUE(watch) NOT NULL"` | 	IssueID     int64              `xorm:"UNIQUE(watch) NOT NULL"` | ||||||
| 	IsWatching  bool           `xorm:"NOT NULL"` | 	IsWatching  bool               `xorm:"NOT NULL"` | ||||||
| 	CreatedUnix util.TimeStamp `xorm:"created NOT NULL"` | 	CreatedUnix timeutil.TimeStamp `xorm:"created NOT NULL"` | ||||||
| 	UpdatedUnix util.TimeStamp `xorm:"updated NOT NULL"` | 	UpdatedUnix timeutil.TimeStamp `xorm:"updated NOT NULL"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // CreateOrUpdateIssueWatch set watching for a user and issue
 | // CreateOrUpdateIssueWatch set watching for a user and issue
 | ||||||
|  |  | ||||||
|  | @ -7,17 +7,17 @@ import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"io" | 	"io" | ||||||
| 
 | 
 | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // LFSMetaObject stores metadata for LFS tracked files.
 | // LFSMetaObject stores metadata for LFS tracked files.
 | ||||||
| type LFSMetaObject struct { | type LFSMetaObject struct { | ||||||
| 	ID           int64          `xorm:"pk autoincr"` | 	ID           int64              `xorm:"pk autoincr"` | ||||||
| 	Oid          string         `xorm:"UNIQUE(s) INDEX NOT NULL"` | 	Oid          string             `xorm:"UNIQUE(s) INDEX NOT NULL"` | ||||||
| 	Size         int64          `xorm:"NOT NULL"` | 	Size         int64              `xorm:"NOT NULL"` | ||||||
| 	RepositoryID int64          `xorm:"UNIQUE(s) INDEX NOT NULL"` | 	RepositoryID int64              `xorm:"UNIQUE(s) INDEX NOT NULL"` | ||||||
| 	Existing     bool           `xorm:"-"` | 	Existing     bool               `xorm:"-"` | ||||||
| 	CreatedUnix  util.TimeStamp `xorm:"created"` | 	CreatedUnix  timeutil.TimeStamp `xorm:"created"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Pointer returns the string representation of an LFS pointer file
 | // Pointer returns the string representation of an LFS pointer file
 | ||||||
|  |  | ||||||
|  | @ -14,16 +14,16 @@ import ( | ||||||
| 	"regexp" | 	"regexp" | ||||||
| 	"strings" | 	"strings" | ||||||
| 
 | 
 | ||||||
| 	"github.com/Unknwon/com" |  | ||||||
| 	"github.com/go-xorm/xorm" |  | ||||||
| 	"xorm.io/core" |  | ||||||
| 
 |  | ||||||
| 	"code.gitea.io/gitea/modules/auth/ldap" | 	"code.gitea.io/gitea/modules/auth/ldap" | ||||||
| 	"code.gitea.io/gitea/modules/auth/oauth2" | 	"code.gitea.io/gitea/modules/auth/oauth2" | ||||||
| 	"code.gitea.io/gitea/modules/auth/pam" | 	"code.gitea.io/gitea/modules/auth/pam" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
|  | 
 | ||||||
|  | 	"github.com/Unknwon/com" | ||||||
|  | 	"github.com/go-xorm/xorm" | ||||||
|  | 	"xorm.io/core" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // LoginType represents an login type.
 | // LoginType represents an login type.
 | ||||||
|  | @ -148,8 +148,8 @@ type LoginSource struct { | ||||||
| 	IsSyncEnabled bool            `xorm:"INDEX NOT NULL DEFAULT false"` | 	IsSyncEnabled bool            `xorm:"INDEX NOT NULL DEFAULT false"` | ||||||
| 	Cfg           core.Conversion `xorm:"TEXT"` | 	Cfg           core.Conversion `xorm:"TEXT"` | ||||||
| 
 | 
 | ||||||
| 	CreatedUnix util.TimeStamp `xorm:"INDEX created"` | 	CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | ||||||
| 	UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` | 	UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Cell2Int64 converts a xorm.Cell type to int64,
 | // Cell2Int64 converts a xorm.Cell type to int64,
 | ||||||
|  |  | ||||||
|  | @ -16,6 +16,7 @@ import ( | ||||||
| 	"code.gitea.io/gitea/modules/markup" | 	"code.gitea.io/gitea/modules/markup" | ||||||
| 	"code.gitea.io/gitea/modules/markup/markdown" | 	"code.gitea.io/gitea/modules/markup/markdown" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
|  | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 	"gopkg.in/gomail.v2" | 	"gopkg.in/gomail.v2" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -47,8 +48,8 @@ func SendTestMail(email string) error { | ||||||
| func SendUserMail(language string, u *User, tpl base.TplName, code, subject, info string) { | func SendUserMail(language string, u *User, tpl base.TplName, code, subject, info string) { | ||||||
| 	data := map[string]interface{}{ | 	data := map[string]interface{}{ | ||||||
| 		"DisplayName":       u.DisplayName(), | 		"DisplayName":       u.DisplayName(), | ||||||
| 		"ActiveCodeLives":   base.MinutesToFriendly(setting.Service.ActiveCodeLives, language), | 		"ActiveCodeLives":   timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, language), | ||||||
| 		"ResetPwdCodeLives": base.MinutesToFriendly(setting.Service.ResetPwdCodeLives, language), | 		"ResetPwdCodeLives": timeutil.MinutesToFriendly(setting.Service.ResetPwdCodeLives, language), | ||||||
| 		"Code":              code, | 		"Code":              code, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -85,7 +86,7 @@ func SendResetPasswordMail(locale Locale, u *User) { | ||||||
| func SendActivateEmailMail(locale Locale, u *User, email *EmailAddress) { | func SendActivateEmailMail(locale Locale, u *User, email *EmailAddress) { | ||||||
| 	data := map[string]interface{}{ | 	data := map[string]interface{}{ | ||||||
| 		"DisplayName":     u.DisplayName(), | 		"DisplayName":     u.DisplayName(), | ||||||
| 		"ActiveCodeLives": base.MinutesToFriendly(setting.Service.ActiveCodeLives, locale.Language()), | 		"ActiveCodeLives": timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, locale.Language()), | ||||||
| 		"Code":            u.GenerateEmailActivateCode(email.Email), | 		"Code":            u.GenerateEmailActivateCode(email.Email), | ||||||
| 		"Email":           email.Email, | 		"Email":           email.Email, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -7,7 +7,7 @@ package migrations | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 
 | 
 | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 
 | 
 | ||||||
| 	"github.com/go-xorm/xorm" | 	"github.com/go-xorm/xorm" | ||||||
| ) | ) | ||||||
|  | @ -19,7 +19,7 @@ func addPullRequestOptions(x *xorm.Engine) error { | ||||||
| 		RepoID      int64                  `xorm:"INDEX(s)"` | 		RepoID      int64                  `xorm:"INDEX(s)"` | ||||||
| 		Type        int                    `xorm:"INDEX(s)"` | 		Type        int                    `xorm:"INDEX(s)"` | ||||||
| 		Config      map[string]interface{} `xorm:"JSON"` | 		Config      map[string]interface{} `xorm:"JSON"` | ||||||
| 		CreatedUnix util.TimeStamp         `xorm:"INDEX CREATED"` | 		CreatedUnix timeutil.TimeStamp     `xorm:"INDEX CREATED"` | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	sess := x.NewSession() | 	sess := x.NewSession() | ||||||
|  |  | ||||||
|  | @ -7,7 +7,7 @@ package migrations | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 
 | 
 | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 
 | 
 | ||||||
| 	"github.com/go-xorm/xorm" | 	"github.com/go-xorm/xorm" | ||||||
| ) | ) | ||||||
|  | @ -15,7 +15,7 @@ import ( | ||||||
| func addIssueClosedTime(x *xorm.Engine) error { | func addIssueClosedTime(x *xorm.Engine) error { | ||||||
| 	// Issue see models/issue.go
 | 	// Issue see models/issue.go
 | ||||||
| 	type Issue struct { | 	type Issue struct { | ||||||
| 		ClosedUnix util.TimeStamp `xorm:"INDEX"` | 		ClosedUnix timeutil.TimeStamp `xorm:"INDEX"` | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if err := x.Sync2(new(Issue)); err != nil { | 	if err := x.Sync2(new(Issue)); err != nil { | ||||||
|  |  | ||||||
|  | @ -5,7 +5,7 @@ | ||||||
| package migrations | package migrations | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 
 | 
 | ||||||
| 	"github.com/go-xorm/xorm" | 	"github.com/go-xorm/xorm" | ||||||
| ) | ) | ||||||
|  | @ -27,10 +27,10 @@ func addMultipleAssignees(x *xorm.Engine) error { | ||||||
| 		IsPull      bool  `xorm:"INDEX"` // Indicates whether is a pull request or not.
 | 		IsPull      bool  `xorm:"INDEX"` // Indicates whether is a pull request or not.
 | ||||||
| 		NumComments int | 		NumComments int | ||||||
| 
 | 
 | ||||||
| 		DeadlineUnix util.TimeStamp `xorm:"INDEX"` | 		DeadlineUnix timeutil.TimeStamp `xorm:"INDEX"` | ||||||
| 		CreatedUnix  util.TimeStamp `xorm:"INDEX created"` | 		CreatedUnix  timeutil.TimeStamp `xorm:"INDEX created"` | ||||||
| 		UpdatedUnix  util.TimeStamp `xorm:"INDEX updated"` | 		UpdatedUnix  timeutil.TimeStamp `xorm:"INDEX updated"` | ||||||
| 		ClosedUnix   util.TimeStamp `xorm:"INDEX"` | 		ClosedUnix   timeutil.TimeStamp `xorm:"INDEX"` | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Updated the comment table
 | 	// Updated the comment table
 | ||||||
|  | @ -53,8 +53,8 @@ func addMultipleAssignees(x *xorm.Engine) error { | ||||||
| 		Content         string `xorm:"TEXT"` | 		Content         string `xorm:"TEXT"` | ||||||
| 		RenderedContent string `xorm:"-"` | 		RenderedContent string `xorm:"-"` | ||||||
| 
 | 
 | ||||||
| 		CreatedUnix util.TimeStamp `xorm:"INDEX created"` | 		CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | ||||||
| 		UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` | 		UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | ||||||
| 
 | 
 | ||||||
| 		// Reference issue in commit message
 | 		// Reference issue in commit message
 | ||||||
| 		CommitSHA string `xorm:"VARCHAR(40)"` | 		CommitSHA string `xorm:"VARCHAR(40)"` | ||||||
|  |  | ||||||
|  | @ -1,7 +1,8 @@ | ||||||
| package migrations | package migrations | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
|  | 
 | ||||||
| 	"github.com/go-xorm/xorm" | 	"github.com/go-xorm/xorm" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -12,8 +13,8 @@ func addU2FReg(x *xorm.Engine) error { | ||||||
| 		UserID      int64 `xorm:"INDEX"` | 		UserID      int64 `xorm:"INDEX"` | ||||||
| 		Raw         []byte | 		Raw         []byte | ||||||
| 		Counter     uint32 | 		Counter     uint32 | ||||||
| 		CreatedUnix util.TimeStamp `xorm:"INDEX created"` | 		CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | ||||||
| 		UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` | 		UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | ||||||
| 	} | 	} | ||||||
| 	return x.Sync2(&U2FRegistration{}) | 	return x.Sync2(&U2FRegistration{}) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -8,11 +8,11 @@ import ( | ||||||
| 	"crypto/sha256" | 	"crypto/sha256" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 
 | 
 | ||||||
|  | 	"code.gitea.io/gitea/modules/generate" | ||||||
|  | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
|  | 
 | ||||||
| 	"github.com/go-xorm/xorm" | 	"github.com/go-xorm/xorm" | ||||||
| 	"golang.org/x/crypto/pbkdf2" | 	"golang.org/x/crypto/pbkdf2" | ||||||
| 
 |  | ||||||
| 	"code.gitea.io/gitea/modules/generate" |  | ||||||
| 	"code.gitea.io/gitea/modules/util" |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func addScratchHash(x *xorm.Engine) error { | func addScratchHash(x *xorm.Engine) error { | ||||||
|  | @ -24,9 +24,9 @@ func addScratchHash(x *xorm.Engine) error { | ||||||
| 		ScratchToken     string | 		ScratchToken     string | ||||||
| 		ScratchSalt      string | 		ScratchSalt      string | ||||||
| 		ScratchHash      string | 		ScratchHash      string | ||||||
| 		LastUsedPasscode string         `xorm:"VARCHAR(10)"` | 		LastUsedPasscode string             `xorm:"VARCHAR(10)"` | ||||||
| 		CreatedUnix      util.TimeStamp `xorm:"INDEX created"` | 		CreatedUnix      timeutil.TimeStamp `xorm:"INDEX created"` | ||||||
| 		UpdatedUnix      util.TimeStamp `xorm:"INDEX updated"` | 		UpdatedUnix      timeutil.TimeStamp `xorm:"INDEX updated"` | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if err := x.Sync2(new(TwoFactor)); err != nil { | 	if err := x.Sync2(new(TwoFactor)); err != nil { | ||||||
|  |  | ||||||
|  | @ -7,7 +7,7 @@ package migrations | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 
 | 
 | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 
 | 
 | ||||||
| 	"github.com/go-xorm/xorm" | 	"github.com/go-xorm/xorm" | ||||||
| ) | ) | ||||||
|  | @ -20,8 +20,8 @@ func addReview(x *xorm.Engine) error { | ||||||
| 		ReviewerID  int64 `xorm:"index"` | 		ReviewerID  int64 `xorm:"index"` | ||||||
| 		IssueID     int64 `xorm:"index"` | 		IssueID     int64 `xorm:"index"` | ||||||
| 		Content     string | 		Content     string | ||||||
| 		CreatedUnix util.TimeStamp `xorm:"INDEX created"` | 		CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | ||||||
| 		UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` | 		UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if err := x.Sync2(new(Review)); err != nil { | 	if err := x.Sync2(new(Review)); err != nil { | ||||||
|  |  | ||||||
|  | @ -7,7 +7,7 @@ package migrations | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 
 | 
 | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 
 | 
 | ||||||
| 	"github.com/go-xorm/xorm" | 	"github.com/go-xorm/xorm" | ||||||
| ) | ) | ||||||
|  | @ -19,7 +19,7 @@ func addPullRequestRebaseWithMerge(x *xorm.Engine) error { | ||||||
| 		RepoID      int64                  `xorm:"INDEX(s)"` | 		RepoID      int64                  `xorm:"INDEX(s)"` | ||||||
| 		Type        int                    `xorm:"INDEX(s)"` | 		Type        int                    `xorm:"INDEX(s)"` | ||||||
| 		Config      map[string]interface{} `xorm:"JSON"` | 		Config      map[string]interface{} `xorm:"JSON"` | ||||||
| 		CreatedUnix util.TimeStamp         `xorm:"INDEX CREATED"` | 		CreatedUnix timeutil.TimeStamp     `xorm:"INDEX CREATED"` | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	sess := x.NewSession() | 	sess := x.NewSession() | ||||||
|  |  | ||||||
|  | @ -5,7 +5,7 @@ | ||||||
| package migrations | package migrations | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 
 | 
 | ||||||
| 	"github.com/go-xorm/xorm" | 	"github.com/go-xorm/xorm" | ||||||
| ) | ) | ||||||
|  | @ -19,9 +19,9 @@ func addUploaderIDForAttachment(x *xorm.Engine) error { | ||||||
| 		UploaderID    int64  `xorm:"INDEX DEFAULT 0"` | 		UploaderID    int64  `xorm:"INDEX DEFAULT 0"` | ||||||
| 		CommentID     int64 | 		CommentID     int64 | ||||||
| 		Name          string | 		Name          string | ||||||
| 		DownloadCount int64          `xorm:"DEFAULT 0"` | 		DownloadCount int64              `xorm:"DEFAULT 0"` | ||||||
| 		Size          int64          `xorm:"DEFAULT 0"` | 		Size          int64              `xorm:"DEFAULT 0"` | ||||||
| 		CreatedUnix   util.TimeStamp `xorm:"created"` | 		CreatedUnix   timeutil.TimeStamp `xorm:"created"` | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return x.Sync2(new(Attachment)) | 	return x.Sync2(new(Attachment)) | ||||||
|  |  | ||||||
|  | @ -7,11 +7,11 @@ package migrations | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 
 | 
 | ||||||
| 	"github.com/go-xorm/xorm" |  | ||||||
| 
 |  | ||||||
| 	"code.gitea.io/gitea/modules/generate" | 	"code.gitea.io/gitea/modules/generate" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
|  | 
 | ||||||
|  | 	"github.com/go-xorm/xorm" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func hashAppToken(x *xorm.Engine) error { | func hashAppToken(x *xorm.Engine) error { | ||||||
|  | @ -26,10 +26,10 @@ func hashAppToken(x *xorm.Engine) error { | ||||||
| 		TokenSalt      string | 		TokenSalt      string | ||||||
| 		TokenLastEight string `xorm:"token_last_eight"` | 		TokenLastEight string `xorm:"token_last_eight"` | ||||||
| 
 | 
 | ||||||
| 		CreatedUnix       util.TimeStamp `xorm:"INDEX created"` | 		CreatedUnix       timeutil.TimeStamp `xorm:"INDEX created"` | ||||||
| 		UpdatedUnix       util.TimeStamp `xorm:"INDEX updated"` | 		UpdatedUnix       timeutil.TimeStamp `xorm:"INDEX updated"` | ||||||
| 		HasRecentActivity bool           `xorm:"-"` | 		HasRecentActivity bool               `xorm:"-"` | ||||||
| 		HasUsed           bool           `xorm:"-"` | 		HasUsed           bool               `xorm:"-"` | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// First remove the index
 | 	// First remove the index
 | ||||||
|  |  | ||||||
|  | @ -7,7 +7,7 @@ package models | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 
 | 
 | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type ( | type ( | ||||||
|  | @ -52,8 +52,8 @@ type Notification struct { | ||||||
| 	Issue      *Issue      `xorm:"-"` | 	Issue      *Issue      `xorm:"-"` | ||||||
| 	Repository *Repository `xorm:"-"` | 	Repository *Repository `xorm:"-"` | ||||||
| 
 | 
 | ||||||
| 	CreatedUnix util.TimeStamp `xorm:"created INDEX NOT NULL"` | 	CreatedUnix timeutil.TimeStamp `xorm:"created INDEX NOT NULL"` | ||||||
| 	UpdatedUnix util.TimeStamp `xorm:"updated INDEX NOT NULL"` | 	UpdatedUnix timeutil.TimeStamp `xorm:"updated INDEX NOT NULL"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // CreateOrUpdateIssueNotifications creates an issue notification
 | // CreateOrUpdateIssueNotifications creates an issue notification
 | ||||||
|  |  | ||||||
|  | @ -11,15 +11,14 @@ import ( | ||||||
| 	"net/url" | 	"net/url" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"github.com/go-xorm/xorm" |  | ||||||
| 	uuid "github.com/satori/go.uuid" |  | ||||||
| 
 |  | ||||||
| 	"code.gitea.io/gitea/modules/secret" | 	"code.gitea.io/gitea/modules/secret" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 
 | 
 | ||||||
| 	"github.com/Unknwon/com" | 	"github.com/Unknwon/com" | ||||||
| 	"github.com/dgrijalva/jwt-go" | 	"github.com/dgrijalva/jwt-go" | ||||||
|  | 	"github.com/go-xorm/xorm" | ||||||
|  | 	uuid "github.com/satori/go.uuid" | ||||||
| 	"golang.org/x/crypto/bcrypt" | 	"golang.org/x/crypto/bcrypt" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -36,8 +35,8 @@ type OAuth2Application struct { | ||||||
| 
 | 
 | ||||||
| 	RedirectURIs []string `xorm:"redirect_uris JSON TEXT"` | 	RedirectURIs []string `xorm:"redirect_uris JSON TEXT"` | ||||||
| 
 | 
 | ||||||
| 	CreatedUnix util.TimeStamp `xorm:"INDEX created"` | 	CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | ||||||
| 	UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` | 	UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // TableName sets the table name to `oauth2_application`
 | // TableName sets the table name to `oauth2_application`
 | ||||||
|  | @ -264,7 +263,7 @@ type OAuth2AuthorizationCode struct { | ||||||
| 	CodeChallenge       string | 	CodeChallenge       string | ||||||
| 	CodeChallengeMethod string | 	CodeChallengeMethod string | ||||||
| 	RedirectURI         string | 	RedirectURI         string | ||||||
| 	ValidUntil          util.TimeStamp `xorm:"index"` | 	ValidUntil          timeutil.TimeStamp `xorm:"index"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // TableName sets the table name to `oauth2_authorization_code`
 | // TableName sets the table name to `oauth2_authorization_code`
 | ||||||
|  | @ -348,8 +347,8 @@ type OAuth2Grant struct { | ||||||
| 	Application   *OAuth2Application `xorm:"-"` | 	Application   *OAuth2Application `xorm:"-"` | ||||||
| 	ApplicationID int64              `xorm:"INDEX unique(user_application)"` | 	ApplicationID int64              `xorm:"INDEX unique(user_application)"` | ||||||
| 	Counter       int64              `xorm:"NOT NULL DEFAULT 1"` | 	Counter       int64              `xorm:"NOT NULL DEFAULT 1"` | ||||||
| 	CreatedUnix   util.TimeStamp     `xorm:"created"` | 	CreatedUnix   timeutil.TimeStamp `xorm:"created"` | ||||||
| 	UpdatedUnix   util.TimeStamp     `xorm:"updated"` | 	UpdatedUnix   timeutil.TimeStamp `xorm:"updated"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // TableName sets the table name to `oauth2_grant`
 | // TableName sets the table name to `oauth2_grant`
 | ||||||
|  |  | ||||||
|  | @ -23,7 +23,7 @@ import ( | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	api "code.gitea.io/gitea/modules/structs" | 	api "code.gitea.io/gitea/modules/structs" | ||||||
| 	"code.gitea.io/gitea/modules/sync" | 	"code.gitea.io/gitea/modules/sync" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 
 | 
 | ||||||
| 	"github.com/Unknwon/com" | 	"github.com/Unknwon/com" | ||||||
| 	"github.com/go-xorm/xorm" | 	"github.com/go-xorm/xorm" | ||||||
|  | @ -72,11 +72,11 @@ type PullRequest struct { | ||||||
| 	ProtectedBranch *ProtectedBranch `xorm:"-"` | 	ProtectedBranch *ProtectedBranch `xorm:"-"` | ||||||
| 	MergeBase       string           `xorm:"VARCHAR(40)"` | 	MergeBase       string           `xorm:"VARCHAR(40)"` | ||||||
| 
 | 
 | ||||||
| 	HasMerged      bool           `xorm:"INDEX"` | 	HasMerged      bool               `xorm:"INDEX"` | ||||||
| 	MergedCommitID string         `xorm:"VARCHAR(40)"` | 	MergedCommitID string             `xorm:"VARCHAR(40)"` | ||||||
| 	MergerID       int64          `xorm:"INDEX"` | 	MergerID       int64              `xorm:"INDEX"` | ||||||
| 	Merger         *User          `xorm:"-"` | 	Merger         *User              `xorm:"-"` | ||||||
| 	MergedUnix     util.TimeStamp `xorm:"updated INDEX"` | 	MergedUnix     timeutil.TimeStamp `xorm:"updated INDEX"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Note: don't try to get Issue because will end up recursive querying.
 | // Note: don't try to get Issue because will end up recursive querying.
 | ||||||
|  | @ -443,7 +443,7 @@ func (pr *PullRequest) manuallyMerged() bool { | ||||||
| 	} | 	} | ||||||
| 	if commit != nil { | 	if commit != nil { | ||||||
| 		pr.MergedCommitID = commit.ID.String() | 		pr.MergedCommitID = commit.ID.String() | ||||||
| 		pr.MergedUnix = util.TimeStamp(commit.Author.When.Unix()) | 		pr.MergedUnix = timeutil.TimeStamp(commit.Author.When.Unix()) | ||||||
| 		pr.Status = PullRequestStatusManuallyMerged | 		pr.Status = PullRequestStatusManuallyMerged | ||||||
| 		merger, _ := GetUserByEmail(commit.Author.Email) | 		merger, _ := GetUserByEmail(commit.Author.Email) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -14,7 +14,7 @@ import ( | ||||||
| 	"code.gitea.io/gitea/modules/process" | 	"code.gitea.io/gitea/modules/process" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	api "code.gitea.io/gitea/modules/structs" | 	api "code.gitea.io/gitea/modules/structs" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 
 | 
 | ||||||
| 	"xorm.io/builder" | 	"xorm.io/builder" | ||||||
| ) | ) | ||||||
|  | @ -32,13 +32,13 @@ type Release struct { | ||||||
| 	Title            string | 	Title            string | ||||||
| 	Sha1             string `xorm:"VARCHAR(40)"` | 	Sha1             string `xorm:"VARCHAR(40)"` | ||||||
| 	NumCommits       int64 | 	NumCommits       int64 | ||||||
| 	NumCommitsBehind int64          `xorm:"-"` | 	NumCommitsBehind int64              `xorm:"-"` | ||||||
| 	Note             string         `xorm:"TEXT"` | 	Note             string             `xorm:"TEXT"` | ||||||
| 	IsDraft          bool           `xorm:"NOT NULL DEFAULT false"` | 	IsDraft          bool               `xorm:"NOT NULL DEFAULT false"` | ||||||
| 	IsPrerelease     bool           `xorm:"NOT NULL DEFAULT false"` | 	IsPrerelease     bool               `xorm:"NOT NULL DEFAULT false"` | ||||||
| 	IsTag            bool           `xorm:"NOT NULL DEFAULT false"` | 	IsTag            bool               `xorm:"NOT NULL DEFAULT false"` | ||||||
| 	Attachments      []*Attachment  `xorm:"-"` | 	Attachments      []*Attachment      `xorm:"-"` | ||||||
| 	CreatedUnix      util.TimeStamp `xorm:"INDEX"` | 	CreatedUnix      timeutil.TimeStamp `xorm:"INDEX"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (r *Release) loadAttributes(e Engine) error { | func (r *Release) loadAttributes(e Engine) error { | ||||||
|  | @ -137,13 +137,13 @@ func createTag(gitRepo *git.Repository, rel *Release) error { | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		rel.Sha1 = commit.ID.String() | 		rel.Sha1 = commit.ID.String() | ||||||
| 		rel.CreatedUnix = util.TimeStamp(commit.Author.When.Unix()) | 		rel.CreatedUnix = timeutil.TimeStamp(commit.Author.When.Unix()) | ||||||
| 		rel.NumCommits, err = commit.CommitsCount() | 		rel.NumCommits, err = commit.CommitsCount() | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return fmt.Errorf("CommitsCount: %v", err) | 			return fmt.Errorf("CommitsCount: %v", err) | ||||||
| 		} | 		} | ||||||
| 	} else { | 	} else { | ||||||
| 		rel.CreatedUnix = util.TimeStampNow() | 		rel.CreatedUnix = timeutil.TimeStampNow() | ||||||
| 	} | 	} | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -34,7 +34,7 @@ import ( | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	api "code.gitea.io/gitea/modules/structs" | 	api "code.gitea.io/gitea/modules/structs" | ||||||
| 	"code.gitea.io/gitea/modules/sync" | 	"code.gitea.io/gitea/modules/sync" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 
 | 
 | ||||||
| 	"github.com/Unknwon/com" | 	"github.com/Unknwon/com" | ||||||
| 	"github.com/go-xorm/xorm" | 	"github.com/go-xorm/xorm" | ||||||
|  | @ -175,8 +175,8 @@ type Repository struct { | ||||||
| 	// Avatar: ID(10-20)-md5(32) - must fit into 64 symbols
 | 	// Avatar: ID(10-20)-md5(32) - must fit into 64 symbols
 | ||||||
| 	Avatar string `xorm:"VARCHAR(64)"` | 	Avatar string `xorm:"VARCHAR(64)"` | ||||||
| 
 | 
 | ||||||
| 	CreatedUnix util.TimeStamp `xorm:"INDEX created"` | 	CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | ||||||
| 	UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` | 	UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // ColorFormat returns a colored string to represent this repo
 | // ColorFormat returns a colored string to represent this repo
 | ||||||
|  | @ -971,7 +971,7 @@ func MigrateRepository(doer, u *User, opts MigrateRepoOptions) (*Repository, err | ||||||
| 			RepoID:         repo.ID, | 			RepoID:         repo.ID, | ||||||
| 			Interval:       setting.Mirror.DefaultInterval, | 			Interval:       setting.Mirror.DefaultInterval, | ||||||
| 			EnablePrune:    true, | 			EnablePrune:    true, | ||||||
| 			NextUpdateUnix: util.TimeStampNow().AddDuration(setting.Mirror.DefaultInterval), | 			NextUpdateUnix: timeutil.TimeStampNow().AddDuration(setting.Mirror.DefaultInterval), | ||||||
| 		}); err != nil { | 		}); err != nil { | ||||||
| 			return repo, fmt.Errorf("InsertOne: %v", err) | 			return repo, fmt.Errorf("InsertOne: %v", err) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | @ -16,6 +16,7 @@ import ( | ||||||
| 	"code.gitea.io/gitea/modules/process" | 	"code.gitea.io/gitea/modules/process" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	"code.gitea.io/gitea/modules/sync" | 	"code.gitea.io/gitea/modules/sync" | ||||||
|  | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/util" | ||||||
| 
 | 
 | ||||||
| 	"github.com/Unknwon/com" | 	"github.com/Unknwon/com" | ||||||
|  | @ -34,8 +35,8 @@ type Mirror struct { | ||||||
| 	Interval    time.Duration | 	Interval    time.Duration | ||||||
| 	EnablePrune bool `xorm:"NOT NULL DEFAULT true"` | 	EnablePrune bool `xorm:"NOT NULL DEFAULT true"` | ||||||
| 
 | 
 | ||||||
| 	UpdatedUnix    util.TimeStamp `xorm:"INDEX"` | 	UpdatedUnix    timeutil.TimeStamp `xorm:"INDEX"` | ||||||
| 	NextUpdateUnix util.TimeStamp `xorm:"INDEX"` | 	NextUpdateUnix timeutil.TimeStamp `xorm:"INDEX"` | ||||||
| 
 | 
 | ||||||
| 	address string `xorm:"-"` | 	address string `xorm:"-"` | ||||||
| } | } | ||||||
|  | @ -43,8 +44,8 @@ type Mirror struct { | ||||||
| // BeforeInsert will be invoked by XORM before inserting a record
 | // BeforeInsert will be invoked by XORM before inserting a record
 | ||||||
| func (m *Mirror) BeforeInsert() { | func (m *Mirror) BeforeInsert() { | ||||||
| 	if m != nil { | 	if m != nil { | ||||||
| 		m.UpdatedUnix = util.TimeStampNow() | 		m.UpdatedUnix = timeutil.TimeStampNow() | ||||||
| 		m.NextUpdateUnix = util.TimeStampNow() | 		m.NextUpdateUnix = timeutil.TimeStampNow() | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -64,7 +65,7 @@ func (m *Mirror) AfterLoad(session *xorm.Session) { | ||||||
| // ScheduleNextUpdate calculates and sets next update time.
 | // ScheduleNextUpdate calculates and sets next update time.
 | ||||||
| func (m *Mirror) ScheduleNextUpdate() { | func (m *Mirror) ScheduleNextUpdate() { | ||||||
| 	if m.Interval != 0 { | 	if m.Interval != 0 { | ||||||
| 		m.NextUpdateUnix = util.TimeStampNow().AddDuration(m.Interval) | 		m.NextUpdateUnix = timeutil.TimeStampNow().AddDuration(m.Interval) | ||||||
| 	} else { | 	} else { | ||||||
| 		m.NextUpdateUnix = 0 | 		m.NextUpdateUnix = 0 | ||||||
| 	} | 	} | ||||||
|  | @ -277,7 +278,7 @@ func (m *Mirror) runSync() ([]*mirrorSyncResult, bool) { | ||||||
| 		cache.Remove(m.Repo.GetCommitsCountCacheKey(branches[i].Name, true)) | 		cache.Remove(m.Repo.GetCommitsCountCacheKey(branches[i].Name, true)) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	m.UpdatedUnix = util.TimeStampNow() | 	m.UpdatedUnix = timeutil.TimeStampNow() | ||||||
| 	return parseRemoteUpdateOutput(output), true | 	return parseRemoteUpdateOutput(output), true | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -7,7 +7,7 @@ package models | ||||||
| import ( | import ( | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 
 | 
 | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 
 | 
 | ||||||
| 	"github.com/Unknwon/com" | 	"github.com/Unknwon/com" | ||||||
| 	"github.com/go-xorm/xorm" | 	"github.com/go-xorm/xorm" | ||||||
|  | @ -17,10 +17,10 @@ import ( | ||||||
| // RepoUnit describes all units of a repository
 | // RepoUnit describes all units of a repository
 | ||||||
| type RepoUnit struct { | type RepoUnit struct { | ||||||
| 	ID          int64 | 	ID          int64 | ||||||
| 	RepoID      int64           `xorm:"INDEX(s)"` | 	RepoID      int64              `xorm:"INDEX(s)"` | ||||||
| 	Type        UnitType        `xorm:"INDEX(s)"` | 	Type        UnitType           `xorm:"INDEX(s)"` | ||||||
| 	Config      core.Conversion `xorm:"TEXT"` | 	Config      core.Conversion    `xorm:"TEXT"` | ||||||
| 	CreatedUnix util.TimeStamp  `xorm:"INDEX CREATED"` | 	CreatedUnix timeutil.TimeStamp `xorm:"INDEX CREATED"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // UnitConfig describes common unit config
 | // UnitConfig describes common unit config
 | ||||||
|  |  | ||||||
|  | @ -8,7 +8,7 @@ import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 
 | 
 | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 
 | 
 | ||||||
| 	"github.com/go-xorm/xorm" | 	"github.com/go-xorm/xorm" | ||||||
| 	"xorm.io/builder" | 	"xorm.io/builder" | ||||||
|  | @ -56,8 +56,8 @@ type Review struct { | ||||||
| 	IssueID    int64  `xorm:"index"` | 	IssueID    int64  `xorm:"index"` | ||||||
| 	Content    string | 	Content    string | ||||||
| 
 | 
 | ||||||
| 	CreatedUnix util.TimeStamp `xorm:"INDEX created"` | 	CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | ||||||
| 	UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` | 	UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | ||||||
| 
 | 
 | ||||||
| 	// CodeComments are the initial code comments of the review
 | 	// CodeComments are the initial code comments of the review
 | ||||||
| 	CodeComments CodeComments `xorm:"-"` | 	CodeComments CodeComments `xorm:"-"` | ||||||
|  | @ -279,7 +279,7 @@ func UpdateReview(r *Review) error { | ||||||
| type PullReviewersWithType struct { | type PullReviewersWithType struct { | ||||||
| 	User              `xorm:"extends"` | 	User              `xorm:"extends"` | ||||||
| 	Type              ReviewType | 	Type              ReviewType | ||||||
| 	ReviewUpdatedUnix util.TimeStamp `xorm:"review_updated_unix"` | 	ReviewUpdatedUnix timeutil.TimeStamp `xorm:"review_updated_unix"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // GetReviewersByPullID gets all reviewers for a pull request with the statuses
 | // GetReviewersByPullID gets all reviewers for a pull request with the statuses
 | ||||||
|  |  | ||||||
|  | @ -26,7 +26,7 @@ import ( | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/process" | 	"code.gitea.io/gitea/modules/process" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 
 | 
 | ||||||
| 	"github.com/Unknwon/com" | 	"github.com/Unknwon/com" | ||||||
| 	"github.com/go-xorm/xorm" | 	"github.com/go-xorm/xorm" | ||||||
|  | @ -62,16 +62,16 @@ type PublicKey struct { | ||||||
| 	Type          KeyType    `xorm:"NOT NULL DEFAULT 1"` | 	Type          KeyType    `xorm:"NOT NULL DEFAULT 1"` | ||||||
| 	LoginSourceID int64      `xorm:"NOT NULL DEFAULT 0"` | 	LoginSourceID int64      `xorm:"NOT NULL DEFAULT 0"` | ||||||
| 
 | 
 | ||||||
| 	CreatedUnix       util.TimeStamp `xorm:"created"` | 	CreatedUnix       timeutil.TimeStamp `xorm:"created"` | ||||||
| 	UpdatedUnix       util.TimeStamp `xorm:"updated"` | 	UpdatedUnix       timeutil.TimeStamp `xorm:"updated"` | ||||||
| 	HasRecentActivity bool           `xorm:"-"` | 	HasRecentActivity bool               `xorm:"-"` | ||||||
| 	HasUsed           bool           `xorm:"-"` | 	HasUsed           bool               `xorm:"-"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // AfterLoad is invoked from XORM after setting the values of all fields of this object.
 | // AfterLoad is invoked from XORM after setting the values of all fields of this object.
 | ||||||
| func (key *PublicKey) AfterLoad() { | func (key *PublicKey) AfterLoad() { | ||||||
| 	key.HasUsed = key.UpdatedUnix > key.CreatedUnix | 	key.HasUsed = key.UpdatedUnix > key.CreatedUnix | ||||||
| 	key.HasRecentActivity = key.UpdatedUnix.AddDuration(7*24*time.Hour) > util.TimeStampNow() | 	key.HasRecentActivity = key.UpdatedUnix.AddDuration(7*24*time.Hour) > timeutil.TimeStampNow() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // OmitEmail returns content of public key without email address.
 | // OmitEmail returns content of public key without email address.
 | ||||||
|  | @ -581,7 +581,7 @@ func UpdatePublicKeyUpdated(id int64) error { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	_, err := x.ID(id).Cols("updated_unix").Update(&PublicKey{ | 	_, err := x.ID(id).Cols("updated_unix").Update(&PublicKey{ | ||||||
| 		UpdatedUnix: util.TimeStampNow(), | 		UpdatedUnix: timeutil.TimeStampNow(), | ||||||
| 	}) | 	}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
|  | @ -714,16 +714,16 @@ type DeployKey struct { | ||||||
| 
 | 
 | ||||||
| 	Mode AccessMode `xorm:"NOT NULL DEFAULT 1"` | 	Mode AccessMode `xorm:"NOT NULL DEFAULT 1"` | ||||||
| 
 | 
 | ||||||
| 	CreatedUnix       util.TimeStamp `xorm:"created"` | 	CreatedUnix       timeutil.TimeStamp `xorm:"created"` | ||||||
| 	UpdatedUnix       util.TimeStamp `xorm:"updated"` | 	UpdatedUnix       timeutil.TimeStamp `xorm:"updated"` | ||||||
| 	HasRecentActivity bool           `xorm:"-"` | 	HasRecentActivity bool               `xorm:"-"` | ||||||
| 	HasUsed           bool           `xorm:"-"` | 	HasUsed           bool               `xorm:"-"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // AfterLoad is invoked from XORM after setting the values of all fields of this object.
 | // AfterLoad is invoked from XORM after setting the values of all fields of this object.
 | ||||||
| func (key *DeployKey) AfterLoad() { | func (key *DeployKey) AfterLoad() { | ||||||
| 	key.HasUsed = key.UpdatedUnix > key.CreatedUnix | 	key.HasUsed = key.UpdatedUnix > key.CreatedUnix | ||||||
| 	key.HasRecentActivity = key.UpdatedUnix.AddDuration(7*24*time.Hour) > util.TimeStampNow() | 	key.HasRecentActivity = key.UpdatedUnix.AddDuration(7*24*time.Hour) > timeutil.TimeStampNow() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // GetContent gets associated public key content.
 | // GetContent gets associated public key content.
 | ||||||
|  |  | ||||||
|  | @ -9,11 +9,11 @@ import ( | ||||||
| 	"crypto/subtle" | 	"crypto/subtle" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	gouuid "github.com/satori/go.uuid" |  | ||||||
| 
 |  | ||||||
| 	"code.gitea.io/gitea/modules/base" | 	"code.gitea.io/gitea/modules/base" | ||||||
| 	"code.gitea.io/gitea/modules/generate" | 	"code.gitea.io/gitea/modules/generate" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
|  | 
 | ||||||
|  | 	gouuid "github.com/satori/go.uuid" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // AccessToken represents a personal access token.
 | // AccessToken represents a personal access token.
 | ||||||
|  | @ -26,16 +26,16 @@ type AccessToken struct { | ||||||
| 	TokenSalt      string | 	TokenSalt      string | ||||||
| 	TokenLastEight string `xorm:"token_last_eight"` | 	TokenLastEight string `xorm:"token_last_eight"` | ||||||
| 
 | 
 | ||||||
| 	CreatedUnix       util.TimeStamp `xorm:"INDEX created"` | 	CreatedUnix       timeutil.TimeStamp `xorm:"INDEX created"` | ||||||
| 	UpdatedUnix       util.TimeStamp `xorm:"INDEX updated"` | 	UpdatedUnix       timeutil.TimeStamp `xorm:"INDEX updated"` | ||||||
| 	HasRecentActivity bool           `xorm:"-"` | 	HasRecentActivity bool               `xorm:"-"` | ||||||
| 	HasUsed           bool           `xorm:"-"` | 	HasUsed           bool               `xorm:"-"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // AfterLoad is invoked from XORM after setting the values of all fields of this object.
 | // AfterLoad is invoked from XORM after setting the values of all fields of this object.
 | ||||||
| func (t *AccessToken) AfterLoad() { | func (t *AccessToken) AfterLoad() { | ||||||
| 	t.HasUsed = t.UpdatedUnix > t.CreatedUnix | 	t.HasUsed = t.UpdatedUnix > t.CreatedUnix | ||||||
| 	t.HasRecentActivity = t.UpdatedUnix.AddDuration(7*24*time.Hour) > util.TimeStampNow() | 	t.HasRecentActivity = t.UpdatedUnix.AddDuration(7*24*time.Hour) > timeutil.TimeStampNow() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // NewAccessToken creates new access token.
 | // NewAccessToken creates new access token.
 | ||||||
|  |  | ||||||
|  | @ -9,7 +9,7 @@ import ( | ||||||
| 	"regexp" | 	"regexp" | ||||||
| 	"strings" | 	"strings" | ||||||
| 
 | 
 | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 
 | 
 | ||||||
| 	"xorm.io/builder" | 	"xorm.io/builder" | ||||||
| ) | ) | ||||||
|  | @ -28,8 +28,8 @@ type Topic struct { | ||||||
| 	ID          int64 | 	ID          int64 | ||||||
| 	Name        string `xorm:"UNIQUE VARCHAR(25)"` | 	Name        string `xorm:"UNIQUE VARCHAR(25)"` | ||||||
| 	RepoCount   int | 	RepoCount   int | ||||||
| 	CreatedUnix util.TimeStamp `xorm:"INDEX created"` | 	CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | ||||||
| 	UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` | 	UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // RepoTopic represents associated repositories and topics
 | // RepoTopic represents associated repositories and topics
 | ||||||
|  |  | ||||||
|  | @ -16,12 +16,12 @@ import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"io" | 	"io" | ||||||
| 
 | 
 | ||||||
| 	"github.com/pquerna/otp/totp" |  | ||||||
| 	"golang.org/x/crypto/pbkdf2" |  | ||||||
| 
 |  | ||||||
| 	"code.gitea.io/gitea/modules/generate" | 	"code.gitea.io/gitea/modules/generate" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
|  | 
 | ||||||
|  | 	"github.com/pquerna/otp/totp" | ||||||
|  | 	"golang.org/x/crypto/pbkdf2" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // TwoFactor represents a two-factor authentication token.
 | // TwoFactor represents a two-factor authentication token.
 | ||||||
|  | @ -31,9 +31,9 @@ type TwoFactor struct { | ||||||
| 	Secret           string | 	Secret           string | ||||||
| 	ScratchSalt      string | 	ScratchSalt      string | ||||||
| 	ScratchHash      string | 	ScratchHash      string | ||||||
| 	LastUsedPasscode string         `xorm:"VARCHAR(10)"` | 	LastUsedPasscode string             `xorm:"VARCHAR(10)"` | ||||||
| 	CreatedUnix      util.TimeStamp `xorm:"INDEX created"` | 	CreatedUnix      timeutil.TimeStamp `xorm:"INDEX created"` | ||||||
| 	UpdatedUnix      util.TimeStamp `xorm:"INDEX updated"` | 	UpdatedUnix      timeutil.TimeStamp `xorm:"INDEX updated"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // GenerateScratchToken recreates the scratch token the user is using.
 | // GenerateScratchToken recreates the scratch token the user is using.
 | ||||||
|  |  | ||||||
|  | @ -6,7 +6,7 @@ package models | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 
 | 
 | ||||||
| 	"github.com/tstranex/u2f" | 	"github.com/tstranex/u2f" | ||||||
| ) | ) | ||||||
|  | @ -17,9 +17,9 @@ type U2FRegistration struct { | ||||||
| 	Name        string | 	Name        string | ||||||
| 	UserID      int64 `xorm:"INDEX"` | 	UserID      int64 `xorm:"INDEX"` | ||||||
| 	Raw         []byte | 	Raw         []byte | ||||||
| 	Counter     uint32         `xorm:"BIGINT"` | 	Counter     uint32             `xorm:"BIGINT"` | ||||||
| 	CreatedUnix util.TimeStamp `xorm:"INDEX created"` | 	CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | ||||||
| 	UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` | 	UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // TableName returns a better table name for U2FRegistration
 | // TableName returns a better table name for U2FRegistration
 | ||||||
|  |  | ||||||
|  | @ -11,7 +11,7 @@ import ( | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"code.gitea.io/gitea/modules/git" | 	"code.gitea.io/gitea/modules/git" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // env keys for git hooks need
 | // env keys for git hooks need
 | ||||||
|  | @ -140,7 +140,7 @@ func PushUpdateAddTag(repo *Repository, gitRepo *git.Repository, tagName string) | ||||||
| 			IsDraft:      false, | 			IsDraft:      false, | ||||||
| 			IsPrerelease: false, | 			IsPrerelease: false, | ||||||
| 			IsTag:        true, | 			IsTag:        true, | ||||||
| 			CreatedUnix:  util.TimeStamp(createdAt.Unix()), | 			CreatedUnix:  timeutil.TimeStamp(createdAt.Unix()), | ||||||
| 		} | 		} | ||||||
| 		if author != nil { | 		if author != nil { | ||||||
| 			rel.PublisherID = author.ID | 			rel.PublisherID = author.ID | ||||||
|  | @ -151,7 +151,7 @@ func PushUpdateAddTag(repo *Repository, gitRepo *git.Repository, tagName string) | ||||||
| 		} | 		} | ||||||
| 	} else { | 	} else { | ||||||
| 		rel.Sha1 = commit.ID.String() | 		rel.Sha1 = commit.ID.String() | ||||||
| 		rel.CreatedUnix = util.TimeStamp(createdAt.Unix()) | 		rel.CreatedUnix = timeutil.TimeStamp(createdAt.Unix()) | ||||||
| 		rel.NumCommits = commitsCount | 		rel.NumCommits = commitsCount | ||||||
| 		rel.IsDraft = false | 		rel.IsDraft = false | ||||||
| 		if rel.IsTag && author != nil { | 		if rel.IsTag && author != nil { | ||||||
|  |  | ||||||
|  | @ -29,6 +29,7 @@ import ( | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	"code.gitea.io/gitea/modules/structs" | 	"code.gitea.io/gitea/modules/structs" | ||||||
| 	api "code.gitea.io/gitea/modules/structs" | 	api "code.gitea.io/gitea/modules/structs" | ||||||
|  | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/util" | ||||||
| 
 | 
 | ||||||
| 	"github.com/Unknwon/com" | 	"github.com/Unknwon/com" | ||||||
|  | @ -110,9 +111,9 @@ type User struct { | ||||||
| 	Language    string `xorm:"VARCHAR(5)"` | 	Language    string `xorm:"VARCHAR(5)"` | ||||||
| 	Description string | 	Description string | ||||||
| 
 | 
 | ||||||
| 	CreatedUnix   util.TimeStamp `xorm:"INDEX created"` | 	CreatedUnix   timeutil.TimeStamp `xorm:"INDEX created"` | ||||||
| 	UpdatedUnix   util.TimeStamp `xorm:"INDEX updated"` | 	UpdatedUnix   timeutil.TimeStamp `xorm:"INDEX updated"` | ||||||
| 	LastLoginUnix util.TimeStamp `xorm:"INDEX"` | 	LastLoginUnix timeutil.TimeStamp `xorm:"INDEX"` | ||||||
| 
 | 
 | ||||||
| 	// Remember visibility choice for convenience, true for private
 | 	// Remember visibility choice for convenience, true for private
 | ||||||
| 	LastRepoVisibility bool | 	LastRepoVisibility bool | ||||||
|  | @ -190,7 +191,7 @@ func (u *User) AfterLoad() { | ||||||
| 
 | 
 | ||||||
| // SetLastLogin set time to last login
 | // SetLastLogin set time to last login
 | ||||||
| func (u *User) SetLastLogin() { | func (u *User) SetLastLogin() { | ||||||
| 	u.LastLoginUnix = util.TimeStampNow() | 	u.LastLoginUnix = timeutil.TimeStampNow() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // UpdateDiffViewStyle updates the users diff view style
 | // UpdateDiffViewStyle updates the users diff view style
 | ||||||
|  |  | ||||||
|  | @ -6,13 +6,13 @@ package models | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // UserHeatmapData represents the data needed to create a heatmap
 | // UserHeatmapData represents the data needed to create a heatmap
 | ||||||
| type UserHeatmapData struct { | type UserHeatmapData struct { | ||||||
| 	Timestamp     util.TimeStamp `json:"timestamp"` | 	Timestamp     timeutil.TimeStamp `json:"timestamp"` | ||||||
| 	Contributions int64          `json:"contributions"` | 	Contributions int64              `json:"contributions"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // GetUserHeatmapDataByUser returns an array of UserHeatmapData
 | // GetUserHeatmapDataByUser returns an array of UserHeatmapData
 | ||||||
|  | @ -35,7 +35,7 @@ func GetUserHeatmapDataByUser(user *User) ([]*UserHeatmapData, error) { | ||||||
| 	sess := x.Select(groupBy+" AS timestamp, count(user_id) as contributions"). | 	sess := x.Select(groupBy+" AS timestamp, count(user_id) as contributions"). | ||||||
| 		Table("action"). | 		Table("action"). | ||||||
| 		Where("user_id = ?", user.ID). | 		Where("user_id = ?", user.ID). | ||||||
| 		And("created_unix > ?", (util.TimeStampNow() - 31536000)) | 		And("created_unix > ?", (timeutil.TimeStampNow() - 31536000)) | ||||||
| 
 | 
 | ||||||
| 	// * Heatmaps for individual users only include actions that the user themself
 | 	// * Heatmaps for individual users only include actions that the user themself
 | ||||||
| 	//   did.
 | 	//   did.
 | ||||||
|  |  | ||||||
|  | @ -23,7 +23,8 @@ import ( | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	api "code.gitea.io/gitea/modules/structs" | 	api "code.gitea.io/gitea/modules/structs" | ||||||
| 	"code.gitea.io/gitea/modules/sync" | 	"code.gitea.io/gitea/modules/sync" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
|  | 
 | ||||||
| 	"github.com/Unknwon/com" | 	"github.com/Unknwon/com" | ||||||
| 	gouuid "github.com/satori/go.uuid" | 	gouuid "github.com/satori/go.uuid" | ||||||
| ) | ) | ||||||
|  | @ -118,8 +119,8 @@ type Webhook struct { | ||||||
| 	Meta         string     `xorm:"TEXT"` // store hook-specific attributes
 | 	Meta         string     `xorm:"TEXT"` // store hook-specific attributes
 | ||||||
| 	LastStatus   HookStatus // Last delivery status
 | 	LastStatus   HookStatus // Last delivery status
 | ||||||
| 
 | 
 | ||||||
| 	CreatedUnix util.TimeStamp `xorm:"INDEX created"` | 	CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | ||||||
| 	UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` | 	UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // AfterLoad updates the webhook object upon setting a column
 | // AfterLoad updates the webhook object upon setting a column
 | ||||||
|  |  | ||||||
|  | @ -20,7 +20,7 @@ import ( | ||||||
| 	"code.gitea.io/gitea/modules/base" | 	"code.gitea.io/gitea/modules/base" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 	"code.gitea.io/gitea/modules/validation" | 	"code.gitea.io/gitea/modules/validation" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -68,7 +68,7 @@ func SignedInID(ctx *macaron.Context, sess session.Store) int64 { | ||||||
| 				} | 				} | ||||||
| 				return 0 | 				return 0 | ||||||
| 			} | 			} | ||||||
| 			t.UpdatedUnix = util.TimeStampNow() | 			t.UpdatedUnix = timeutil.TimeStampNow() | ||||||
| 			if err = models.UpdateAccessToken(t); err != nil { | 			if err = models.UpdateAccessToken(t); err != nil { | ||||||
| 				log.Error("UpdateAccessToken: %v", err) | 				log.Error("UpdateAccessToken: %v", err) | ||||||
| 			} | 			} | ||||||
|  | @ -210,7 +210,7 @@ func SignedInUser(ctx *macaron.Context, sess session.Store) (*models.User, bool) | ||||||
| 						return nil, false | 						return nil, false | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 				token.UpdatedUnix = util.TimeStampNow() | 				token.UpdatedUnix = timeutil.TimeStampNow() | ||||||
| 				if err = models.UpdateAccessToken(token); err != nil { | 				if err = models.UpdateAccessToken(token); err != nil { | ||||||
| 					log.Error("UpdateAccessToken:  %v", err) | 					log.Error("UpdateAccessToken:  %v", err) | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
|  | @ -12,7 +12,6 @@ import ( | ||||||
| 	"encoding/base64" | 	"encoding/base64" | ||||||
| 	"encoding/hex" | 	"encoding/hex" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"html/template" |  | ||||||
| 	"io" | 	"io" | ||||||
| 	"math" | 	"math" | ||||||
| 	"net/http" | 	"net/http" | ||||||
|  | @ -29,10 +28,8 @@ import ( | ||||||
| 	"code.gitea.io/gitea/modules/git" | 	"code.gitea.io/gitea/modules/git" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	"code.gitea.io/gitea/modules/util" |  | ||||||
| 
 | 
 | ||||||
| 	"github.com/Unknwon/com" | 	"github.com/Unknwon/com" | ||||||
| 	"github.com/Unknwon/i18n" |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // EncodeMD5 encodes string to md5 hex value.
 | // EncodeMD5 encodes string to md5 hex value.
 | ||||||
|  | @ -217,154 +214,6 @@ func AvatarLink(email string) string { | ||||||
| 	return SizedAvatarLink(email, DefaultAvatarSize) | 	return SizedAvatarLink(email, DefaultAvatarSize) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Seconds-based time units
 |  | ||||||
| const ( |  | ||||||
| 	Minute = 60 |  | ||||||
| 	Hour   = 60 * Minute |  | ||||||
| 	Day    = 24 * Hour |  | ||||||
| 	Week   = 7 * Day |  | ||||||
| 	Month  = 30 * Day |  | ||||||
| 	Year   = 12 * Month |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| func computeTimeDiff(diff int64, lang string) (int64, string) { |  | ||||||
| 	diffStr := "" |  | ||||||
| 	switch { |  | ||||||
| 	case diff <= 0: |  | ||||||
| 		diff = 0 |  | ||||||
| 		diffStr = i18n.Tr(lang, "tool.now") |  | ||||||
| 	case diff < 2: |  | ||||||
| 		diff = 0 |  | ||||||
| 		diffStr = i18n.Tr(lang, "tool.1s") |  | ||||||
| 	case diff < 1*Minute: |  | ||||||
| 		diffStr = i18n.Tr(lang, "tool.seconds", diff) |  | ||||||
| 		diff = 0 |  | ||||||
| 
 |  | ||||||
| 	case diff < 2*Minute: |  | ||||||
| 		diff -= 1 * Minute |  | ||||||
| 		diffStr = i18n.Tr(lang, "tool.1m") |  | ||||||
| 	case diff < 1*Hour: |  | ||||||
| 		diffStr = i18n.Tr(lang, "tool.minutes", diff/Minute) |  | ||||||
| 		diff -= diff / Minute * Minute |  | ||||||
| 
 |  | ||||||
| 	case diff < 2*Hour: |  | ||||||
| 		diff -= 1 * Hour |  | ||||||
| 		diffStr = i18n.Tr(lang, "tool.1h") |  | ||||||
| 	case diff < 1*Day: |  | ||||||
| 		diffStr = i18n.Tr(lang, "tool.hours", diff/Hour) |  | ||||||
| 		diff -= diff / Hour * Hour |  | ||||||
| 
 |  | ||||||
| 	case diff < 2*Day: |  | ||||||
| 		diff -= 1 * Day |  | ||||||
| 		diffStr = i18n.Tr(lang, "tool.1d") |  | ||||||
| 	case diff < 1*Week: |  | ||||||
| 		diffStr = i18n.Tr(lang, "tool.days", diff/Day) |  | ||||||
| 		diff -= diff / Day * Day |  | ||||||
| 
 |  | ||||||
| 	case diff < 2*Week: |  | ||||||
| 		diff -= 1 * Week |  | ||||||
| 		diffStr = i18n.Tr(lang, "tool.1w") |  | ||||||
| 	case diff < 1*Month: |  | ||||||
| 		diffStr = i18n.Tr(lang, "tool.weeks", diff/Week) |  | ||||||
| 		diff -= diff / Week * Week |  | ||||||
| 
 |  | ||||||
| 	case diff < 2*Month: |  | ||||||
| 		diff -= 1 * Month |  | ||||||
| 		diffStr = i18n.Tr(lang, "tool.1mon") |  | ||||||
| 	case diff < 1*Year: |  | ||||||
| 		diffStr = i18n.Tr(lang, "tool.months", diff/Month) |  | ||||||
| 		diff -= diff / Month * Month |  | ||||||
| 
 |  | ||||||
| 	case diff < 2*Year: |  | ||||||
| 		diff -= 1 * Year |  | ||||||
| 		diffStr = i18n.Tr(lang, "tool.1y") |  | ||||||
| 	default: |  | ||||||
| 		diffStr = i18n.Tr(lang, "tool.years", diff/Year) |  | ||||||
| 		diff -= (diff / Year) * Year |  | ||||||
| 	} |  | ||||||
| 	return diff, diffStr |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // MinutesToFriendly returns a user friendly string with number of minutes
 |  | ||||||
| // converted to hours and minutes.
 |  | ||||||
| func MinutesToFriendly(minutes int, lang string) string { |  | ||||||
| 	duration := time.Duration(minutes) * time.Minute |  | ||||||
| 	return TimeSincePro(time.Now().Add(-duration), lang) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // TimeSincePro calculates the time interval and generate full user-friendly string.
 |  | ||||||
| func TimeSincePro(then time.Time, lang string) string { |  | ||||||
| 	return timeSincePro(then, time.Now(), lang) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func timeSincePro(then, now time.Time, lang string) string { |  | ||||||
| 	diff := now.Unix() - then.Unix() |  | ||||||
| 
 |  | ||||||
| 	if then.After(now) { |  | ||||||
| 		return i18n.Tr(lang, "tool.future") |  | ||||||
| 	} |  | ||||||
| 	if diff == 0 { |  | ||||||
| 		return i18n.Tr(lang, "tool.now") |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	var timeStr, diffStr string |  | ||||||
| 	for { |  | ||||||
| 		if diff == 0 { |  | ||||||
| 			break |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		diff, diffStr = computeTimeDiff(diff, lang) |  | ||||||
| 		timeStr += ", " + diffStr |  | ||||||
| 	} |  | ||||||
| 	return strings.TrimPrefix(timeStr, ", ") |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 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 - then |  | ||||||
| 	if then > now { |  | ||||||
| 		lbl = "tool.from_now" |  | ||||||
| 		diff = then - now |  | ||||||
| 	} |  | ||||||
| 	if diff <= 0 { |  | ||||||
| 		return i18n.Tr(lang, "tool.now") |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	_, diffStr := computeTimeDiff(diff, lang) |  | ||||||
| 	return i18n.Tr(lang, lbl, diffStr) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // RawTimeSince retrieves i18n key of time since t
 |  | ||||||
| func RawTimeSince(t time.Time, lang string) string { |  | ||||||
| 	return timeSince(t, time.Now(), lang) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // TimeSince calculates the time interval and generate user-friendly string.
 |  | ||||||
| func TimeSince(then time.Time, lang string) template.HTML { |  | ||||||
| 	return htmlTimeSince(then, time.Now(), lang) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func htmlTimeSince(then, now time.Time, lang string) template.HTML { |  | ||||||
| 	return template.HTML(fmt.Sprintf(`<span class="time-since" title="%s">%s</span>`, |  | ||||||
| 		then.Format(setting.TimeFormat), |  | ||||||
| 		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
 | // Storage space size types
 | ||||||
| const ( | const ( | ||||||
| 	Byte  = 1 | 	Byte  = 1 | ||||||
|  |  | ||||||
|  | @ -2,43 +2,13 @@ package base | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"net/url" | 	"net/url" | ||||||
| 	"os" |  | ||||||
| 	"testing" | 	"testing" | ||||||
| 	"time" |  | ||||||
| 
 | 
 | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 
 | 
 | ||||||
| 	"github.com/Unknwon/i18n" |  | ||||||
| 	macaroni18n "github.com/go-macaron/i18n" |  | ||||||
| 	"github.com/stretchr/testify/assert" | 	"github.com/stretchr/testify/assert" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var BaseDate time.Time |  | ||||||
| 
 |  | ||||||
| // time durations
 |  | ||||||
| const ( |  | ||||||
| 	DayDur   = 24 * time.Hour |  | ||||||
| 	WeekDur  = 7 * DayDur |  | ||||||
| 	MonthDur = 30 * DayDur |  | ||||||
| 	YearDur  = 12 * MonthDur |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| func TestMain(m *testing.M) { |  | ||||||
| 	// setup
 |  | ||||||
| 	macaroni18n.I18n(macaroni18n.Options{ |  | ||||||
| 		Directory:   "../../options/locale/", |  | ||||||
| 		DefaultLang: "en-US", |  | ||||||
| 		Langs:       []string{"en-US"}, |  | ||||||
| 		Names:       []string{"english"}, |  | ||||||
| 	}) |  | ||||||
| 	BaseDate = time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC) |  | ||||||
| 
 |  | ||||||
| 	// run the tests
 |  | ||||||
| 	retVal := m.Run() |  | ||||||
| 
 |  | ||||||
| 	os.Exit(retVal) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func TestEncodeMD5(t *testing.T) { | func TestEncodeMD5(t *testing.T) { | ||||||
| 	assert.Equal(t, | 	assert.Equal(t, | ||||||
| 		"3858f62230ac3c915f300c664312c63f", | 		"3858f62230ac3c915f300c664312c63f", | ||||||
|  | @ -131,125 +101,6 @@ func TestAvatarLink(t *testing.T) { | ||||||
| 	) | 	) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestComputeTimeDiff(t *testing.T) { |  | ||||||
| 	// test that for each offset in offsets,
 |  | ||||||
| 	// computeTimeDiff(base + offset) == (offset, str)
 |  | ||||||
| 	test := func(base int64, str string, offsets ...int64) { |  | ||||||
| 		for _, offset := range offsets { |  | ||||||
| 			diff, diffStr := computeTimeDiff(base+offset, "en") |  | ||||||
| 			assert.Equal(t, offset, diff) |  | ||||||
| 			assert.Equal(t, str, diffStr) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	test(0, "now", 0) |  | ||||||
| 	test(1, "1 second", 0) |  | ||||||
| 	test(2, "2 seconds", 0) |  | ||||||
| 	test(Minute, "1 minute", 0, 1, 30, Minute-1) |  | ||||||
| 	test(2*Minute, "2 minutes", 0, Minute-1) |  | ||||||
| 	test(Hour, "1 hour", 0, 1, Hour-1) |  | ||||||
| 	test(5*Hour, "5 hours", 0, Hour-1) |  | ||||||
| 	test(Day, "1 day", 0, 1, Day-1) |  | ||||||
| 	test(5*Day, "5 days", 0, Day-1) |  | ||||||
| 	test(Week, "1 week", 0, 1, Week-1) |  | ||||||
| 	test(3*Week, "3 weeks", 0, 4*Day+25000) |  | ||||||
| 	test(Month, "1 month", 0, 1, Month-1) |  | ||||||
| 	test(10*Month, "10 months", 0, Month-1) |  | ||||||
| 	test(Year, "1 year", 0, Year-1) |  | ||||||
| 	test(3*Year, "3 years", 0, Year-1) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func TestMinutesToFriendly(t *testing.T) { |  | ||||||
| 	// test that a number of minutes yields the expected string
 |  | ||||||
| 	test := func(expected string, minutes int) { |  | ||||||
| 		actual := MinutesToFriendly(minutes, "en") |  | ||||||
| 		assert.Equal(t, expected, actual) |  | ||||||
| 	} |  | ||||||
| 	test("1 minute", 1) |  | ||||||
| 	test("2 minutes", 2) |  | ||||||
| 	test("1 hour", 60) |  | ||||||
| 	test("1 hour, 1 minute", 61) |  | ||||||
| 	test("1 hour, 2 minutes", 62) |  | ||||||
| 	test("2 hours", 120) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func TestTimeSince(t *testing.T) { |  | ||||||
| 	assert.Equal(t, "now", timeSince(BaseDate, BaseDate, "en")) |  | ||||||
| 
 |  | ||||||
| 	// test that each diff in `diffs` yields the expected string
 |  | ||||||
| 	test := func(expected string, diffs ...time.Duration) { |  | ||||||
| 		for _, diff := range diffs { |  | ||||||
| 			actual := timeSince(BaseDate, BaseDate.Add(diff), "en") |  | ||||||
| 			assert.Equal(t, i18n.Tr("en", "tool.ago", expected), actual) |  | ||||||
| 			actual = timeSince(BaseDate.Add(diff), BaseDate, "en") |  | ||||||
| 			assert.Equal(t, i18n.Tr("en", "tool.from_now", expected), actual) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	test("1 second", time.Second, time.Second+50*time.Millisecond) |  | ||||||
| 	test("2 seconds", 2*time.Second, 2*time.Second+50*time.Millisecond) |  | ||||||
| 	test("1 minute", time.Minute, time.Minute+30*time.Second) |  | ||||||
| 	test("2 minutes", 2*time.Minute, 2*time.Minute+30*time.Second) |  | ||||||
| 	test("1 hour", time.Hour, time.Hour+30*time.Minute) |  | ||||||
| 	test("2 hours", 2*time.Hour, 2*time.Hour+30*time.Minute) |  | ||||||
| 	test("1 day", DayDur, DayDur+12*time.Hour) |  | ||||||
| 	test("2 days", 2*DayDur, 2*DayDur+12*time.Hour) |  | ||||||
| 	test("1 week", WeekDur, WeekDur+3*DayDur) |  | ||||||
| 	test("2 weeks", 2*WeekDur, 2*WeekDur+3*DayDur) |  | ||||||
| 	test("1 month", MonthDur, MonthDur+15*DayDur) |  | ||||||
| 	test("2 months", 2*MonthDur, 2*MonthDur+15*DayDur) |  | ||||||
| 	test("1 year", YearDur, YearDur+6*MonthDur) |  | ||||||
| 	test("2 years", 2*YearDur, 2*YearDur+6*MonthDur) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func TestTimeSincePro(t *testing.T) { |  | ||||||
| 	assert.Equal(t, "now", timeSincePro(BaseDate, BaseDate, "en")) |  | ||||||
| 
 |  | ||||||
| 	// test that a difference of `diff` yields the expected string
 |  | ||||||
| 	test := func(expected string, diff time.Duration) { |  | ||||||
| 		actual := timeSincePro(BaseDate, BaseDate.Add(diff), "en") |  | ||||||
| 		assert.Equal(t, expected, actual) |  | ||||||
| 		assert.Equal(t, "future", timeSincePro(BaseDate.Add(diff), BaseDate, "en")) |  | ||||||
| 	} |  | ||||||
| 	test("1 second", time.Second) |  | ||||||
| 	test("2 seconds", 2*time.Second) |  | ||||||
| 	test("1 minute", time.Minute) |  | ||||||
| 	test("1 minute, 1 second", time.Minute+time.Second) |  | ||||||
| 	test("1 minute, 59 seconds", time.Minute+59*time.Second) |  | ||||||
| 	test("2 minutes", 2*time.Minute) |  | ||||||
| 	test("1 hour", time.Hour) |  | ||||||
| 	test("1 hour, 1 second", time.Hour+time.Second) |  | ||||||
| 	test("1 hour, 59 minutes, 59 seconds", time.Hour+59*time.Minute+59*time.Second) |  | ||||||
| 	test("2 hours", 2*time.Hour) |  | ||||||
| 	test("1 day", DayDur) |  | ||||||
| 	test("1 day, 23 hours, 59 minutes, 59 seconds", |  | ||||||
| 		DayDur+23*time.Hour+59*time.Minute+59*time.Second) |  | ||||||
| 	test("2 days", 2*DayDur) |  | ||||||
| 	test("1 week", WeekDur) |  | ||||||
| 	test("2 weeks", 2*WeekDur) |  | ||||||
| 	test("1 month", MonthDur) |  | ||||||
| 	test("3 months", 3*MonthDur) |  | ||||||
| 	test("1 year", YearDur) |  | ||||||
| 	test("2 years, 3 months, 1 week, 2 days, 4 hours, 12 minutes, 17 seconds", |  | ||||||
| 		2*YearDur+3*MonthDur+WeekDur+2*DayDur+4*time.Hour+ |  | ||||||
| 			12*time.Minute+17*time.Second) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func TestHtmlTimeSince(t *testing.T) { |  | ||||||
| 	setting.TimeFormat = time.UnixDate |  | ||||||
| 	// test that `diff` yields a result containing `expected`
 |  | ||||||
| 	test := func(expected string, diff time.Duration) { |  | ||||||
| 		actual := htmlTimeSince(BaseDate, BaseDate.Add(diff), "en") |  | ||||||
| 		assert.Contains(t, actual, `title="Sat Jan  1 00:00:00 UTC 2000"`) |  | ||||||
| 		assert.Contains(t, actual, expected) |  | ||||||
| 	} |  | ||||||
| 	test("1 second", time.Second) |  | ||||||
| 	test("3 minutes", 3*time.Minute+5*time.Second) |  | ||||||
| 	test("1 day", DayDur+18*time.Hour) |  | ||||||
| 	test("1 week", WeekDur+6*DayDur) |  | ||||||
| 	test("3 months", 3*MonthDur+3*WeekDur) |  | ||||||
| 	test("2 years", 2*YearDur) |  | ||||||
| 	test("3 years", 3*YearDur+11*MonthDur+4*WeekDur) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func TestFileSize(t *testing.T) { | func TestFileSize(t *testing.T) { | ||||||
| 	var size int64 = 512 | 	var size int64 = 512 | ||||||
| 	assert.Equal(t, "512B", FileSize(size)) | 	assert.Equal(t, "512B", FileSize(size)) | ||||||
|  |  | ||||||
|  | @ -21,7 +21,7 @@ import ( | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/migrations/base" | 	"code.gitea.io/gitea/modules/migrations/base" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 
 | 
 | ||||||
| 	gouuid "github.com/satori/go.uuid" | 	gouuid "github.com/satori/go.uuid" | ||||||
| ) | ) | ||||||
|  | @ -106,12 +106,12 @@ func (g *GiteaLocalUploader) CreateTopics(topics ...string) error { | ||||||
| func (g *GiteaLocalUploader) CreateMilestones(milestones ...*base.Milestone) error { | func (g *GiteaLocalUploader) CreateMilestones(milestones ...*base.Milestone) error { | ||||||
| 	var mss = make([]*models.Milestone, 0, len(milestones)) | 	var mss = make([]*models.Milestone, 0, len(milestones)) | ||||||
| 	for _, milestone := range milestones { | 	for _, milestone := range milestones { | ||||||
| 		var deadline util.TimeStamp | 		var deadline timeutil.TimeStamp | ||||||
| 		if milestone.Deadline != nil { | 		if milestone.Deadline != nil { | ||||||
| 			deadline = util.TimeStamp(milestone.Deadline.Unix()) | 			deadline = timeutil.TimeStamp(milestone.Deadline.Unix()) | ||||||
| 		} | 		} | ||||||
| 		if deadline == 0 { | 		if deadline == 0 { | ||||||
| 			deadline = util.TimeStamp(time.Date(9999, 1, 1, 0, 0, 0, 0, setting.UILocation).Unix()) | 			deadline = timeutil.TimeStamp(time.Date(9999, 1, 1, 0, 0, 0, 0, setting.DefaultUILocation).Unix()) | ||||||
| 		} | 		} | ||||||
| 		var ms = models.Milestone{ | 		var ms = models.Milestone{ | ||||||
| 			RepoID:       g.repo.ID, | 			RepoID:       g.repo.ID, | ||||||
|  | @ -121,7 +121,7 @@ func (g *GiteaLocalUploader) CreateMilestones(milestones ...*base.Milestone) err | ||||||
| 			DeadlineUnix: deadline, | 			DeadlineUnix: deadline, | ||||||
| 		} | 		} | ||||||
| 		if ms.IsClosed && milestone.Closed != nil { | 		if ms.IsClosed && milestone.Closed != nil { | ||||||
| 			ms.ClosedDateUnix = util.TimeStamp(milestone.Closed.Unix()) | 			ms.ClosedDateUnix = timeutil.TimeStamp(milestone.Closed.Unix()) | ||||||
| 		} | 		} | ||||||
| 		mss = append(mss, &ms) | 		mss = append(mss, &ms) | ||||||
| 	} | 	} | ||||||
|  | @ -175,7 +175,7 @@ func (g *GiteaLocalUploader) CreateReleases(releases ...*base.Release) error { | ||||||
| 			IsDraft:      release.Draft, | 			IsDraft:      release.Draft, | ||||||
| 			IsPrerelease: release.Prerelease, | 			IsPrerelease: release.Prerelease, | ||||||
| 			IsTag:        false, | 			IsTag:        false, | ||||||
| 			CreatedUnix:  util.TimeStamp(release.Created.Unix()), | 			CreatedUnix:  timeutil.TimeStamp(release.Created.Unix()), | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// calc NumCommits
 | 		// calc NumCommits
 | ||||||
|  | @ -194,7 +194,7 @@ func (g *GiteaLocalUploader) CreateReleases(releases ...*base.Release) error { | ||||||
| 				Name:          asset.Name, | 				Name:          asset.Name, | ||||||
| 				DownloadCount: int64(*asset.DownloadCount), | 				DownloadCount: int64(*asset.DownloadCount), | ||||||
| 				Size:          int64(*asset.Size), | 				Size:          int64(*asset.Size), | ||||||
| 				CreatedUnix:   util.TimeStamp(asset.Created.Unix()), | 				CreatedUnix:   timeutil.TimeStamp(asset.Created.Unix()), | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			// download attachment
 | 			// download attachment
 | ||||||
|  | @ -265,10 +265,10 @@ func (g *GiteaLocalUploader) CreateIssues(issues ...*base.Issue) error { | ||||||
| 			IsLocked:         issue.IsLocked, | 			IsLocked:         issue.IsLocked, | ||||||
| 			MilestoneID:      milestoneID, | 			MilestoneID:      milestoneID, | ||||||
| 			Labels:           labels, | 			Labels:           labels, | ||||||
| 			CreatedUnix:      util.TimeStamp(issue.Created.Unix()), | 			CreatedUnix:      timeutil.TimeStamp(issue.Created.Unix()), | ||||||
| 		} | 		} | ||||||
| 		if issue.Closed != nil { | 		if issue.Closed != nil { | ||||||
| 			is.ClosedUnix = util.TimeStamp(issue.Closed.Unix()) | 			is.ClosedUnix = timeutil.TimeStamp(issue.Closed.Unix()) | ||||||
| 		} | 		} | ||||||
| 		// TODO: add reactions
 | 		// TODO: add reactions
 | ||||||
| 		iss = append(iss, &is) | 		iss = append(iss, &is) | ||||||
|  | @ -307,7 +307,7 @@ func (g *GiteaLocalUploader) CreateComments(comments ...*base.Comment) error { | ||||||
| 			OriginalAuthor:   comment.PosterName, | 			OriginalAuthor:   comment.PosterName, | ||||||
| 			OriginalAuthorID: comment.PosterID, | 			OriginalAuthorID: comment.PosterID, | ||||||
| 			Content:          comment.Content, | 			Content:          comment.Content, | ||||||
| 			CreatedUnix:      util.TimeStamp(comment.Created.Unix()), | 			CreatedUnix:      timeutil.TimeStamp(comment.Created.Unix()), | ||||||
| 		}) | 		}) | ||||||
| 
 | 
 | ||||||
| 		// TODO: Reactions
 | 		// TODO: Reactions
 | ||||||
|  | @ -453,15 +453,15 @@ func (g *GiteaLocalUploader) newPullRequest(pr *base.PullRequest) (*models.PullR | ||||||
| 			IsClosed:         pr.State == "closed", | 			IsClosed:         pr.State == "closed", | ||||||
| 			IsLocked:         pr.IsLocked, | 			IsLocked:         pr.IsLocked, | ||||||
| 			Labels:           labels, | 			Labels:           labels, | ||||||
| 			CreatedUnix:      util.TimeStamp(pr.Created.Unix()), | 			CreatedUnix:      timeutil.TimeStamp(pr.Created.Unix()), | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if pullRequest.Issue.IsClosed && pr.Closed != nil { | 	if pullRequest.Issue.IsClosed && pr.Closed != nil { | ||||||
| 		pullRequest.Issue.ClosedUnix = util.TimeStamp(pr.Closed.Unix()) | 		pullRequest.Issue.ClosedUnix = timeutil.TimeStamp(pr.Closed.Unix()) | ||||||
| 	} | 	} | ||||||
| 	if pullRequest.HasMerged && pr.MergedTime != nil { | 	if pullRequest.HasMerged && pr.MergedTime != nil { | ||||||
| 		pullRequest.MergedUnix = util.TimeStamp(pr.MergedTime.Unix()) | 		pullRequest.MergedUnix = timeutil.TimeStamp(pr.MergedTime.Unix()) | ||||||
| 		pullRequest.MergedCommitID = pr.MergeCommitSHA | 		pullRequest.MergedCommitID = pr.MergeCommitSHA | ||||||
| 		pullRequest.MergerID = g.doer.ID | 		pullRequest.MergerID = g.doer.ID | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -21,7 +21,7 @@ import ( | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	api "code.gitea.io/gitea/modules/structs" | 	api "code.gitea.io/gitea/modules/structs" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // Merge merges pull request to base repository.
 | // Merge merges pull request to base repository.
 | ||||||
|  | @ -258,7 +258,7 @@ func Merge(pr *models.PullRequest, doer *models.User, baseGitRepo *git.Repositor | ||||||
| 		return fmt.Errorf("GetBranchCommit: %v", err) | 		return fmt.Errorf("GetBranchCommit: %v", err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	pr.MergedUnix = util.TimeStampNow() | 	pr.MergedUnix = timeutil.TimeStampNow() | ||||||
| 	pr.Merger = doer | 	pr.Merger = doer | ||||||
| 	pr.MergerID = doer.ID | 	pr.MergerID = doer.ID | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -278,6 +278,8 @@ var ( | ||||||
| 
 | 
 | ||||||
| 	// Time settings
 | 	// Time settings
 | ||||||
| 	TimeFormat string | 	TimeFormat string | ||||||
|  | 	// UILocation is the location on the UI, so that we can display the time on UI.
 | ||||||
|  | 	DefaultUILocation = time.Local | ||||||
| 
 | 
 | ||||||
| 	CSRFCookieName     = "_csrf" | 	CSRFCookieName     = "_csrf" | ||||||
| 	CSRFCookieHTTPOnly = true | 	CSRFCookieHTTPOnly = true | ||||||
|  | @ -356,10 +358,6 @@ var ( | ||||||
| 	HasRobotsTxt      bool | 	HasRobotsTxt      bool | ||||||
| 	InternalToken     string // internal access token
 | 	InternalToken     string // internal access token
 | ||||||
| 	IterateBufferSize int | 	IterateBufferSize int | ||||||
| 
 |  | ||||||
| 	// UILocation is the location on the UI, so that we can display the time on UI.
 |  | ||||||
| 	// Currently only show the default time.Local, it could be added to app.ini after UI is ready
 |  | ||||||
| 	UILocation = time.Local |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // DateLang transforms standard language locale name to corresponding value in datetime plugin.
 | // DateLang transforms standard language locale name to corresponding value in datetime plugin.
 | ||||||
|  | @ -792,32 +790,47 @@ func NewContext() { | ||||||
| 	AttachmentMaxFiles = sec.Key("MAX_FILES").MustInt(5) | 	AttachmentMaxFiles = sec.Key("MAX_FILES").MustInt(5) | ||||||
| 	AttachmentEnabled = sec.Key("ENABLED").MustBool(true) | 	AttachmentEnabled = sec.Key("ENABLED").MustBool(true) | ||||||
| 
 | 
 | ||||||
| 	TimeFormatKey := Cfg.Section("time").Key("FORMAT").MustString("RFC1123") | 	timeFormatKey := Cfg.Section("time").Key("FORMAT").MustString("") | ||||||
| 	TimeFormat = map[string]string{ | 	if timeFormatKey != "" { | ||||||
| 		"ANSIC":       time.ANSIC, | 		TimeFormat = map[string]string{ | ||||||
| 		"UnixDate":    time.UnixDate, | 			"ANSIC":       time.ANSIC, | ||||||
| 		"RubyDate":    time.RubyDate, | 			"UnixDate":    time.UnixDate, | ||||||
| 		"RFC822":      time.RFC822, | 			"RubyDate":    time.RubyDate, | ||||||
| 		"RFC822Z":     time.RFC822Z, | 			"RFC822":      time.RFC822, | ||||||
| 		"RFC850":      time.RFC850, | 			"RFC822Z":     time.RFC822Z, | ||||||
| 		"RFC1123":     time.RFC1123, | 			"RFC850":      time.RFC850, | ||||||
| 		"RFC1123Z":    time.RFC1123Z, | 			"RFC1123":     time.RFC1123, | ||||||
| 		"RFC3339":     time.RFC3339, | 			"RFC1123Z":    time.RFC1123Z, | ||||||
| 		"RFC3339Nano": time.RFC3339Nano, | 			"RFC3339":     time.RFC3339, | ||||||
| 		"Kitchen":     time.Kitchen, | 			"RFC3339Nano": time.RFC3339Nano, | ||||||
| 		"Stamp":       time.Stamp, | 			"Kitchen":     time.Kitchen, | ||||||
| 		"StampMilli":  time.StampMilli, | 			"Stamp":       time.Stamp, | ||||||
| 		"StampMicro":  time.StampMicro, | 			"StampMilli":  time.StampMilli, | ||||||
| 		"StampNano":   time.StampNano, | 			"StampMicro":  time.StampMicro, | ||||||
| 	}[TimeFormatKey] | 			"StampNano":   time.StampNano, | ||||||
| 	// When the TimeFormatKey does not exist in the previous map e.g.'2006-01-02 15:04:05'
 | 		}[timeFormatKey] | ||||||
| 	if len(TimeFormat) == 0 { | 		// When the TimeFormatKey does not exist in the previous map e.g.'2006-01-02 15:04:05'
 | ||||||
| 		TimeFormat = TimeFormatKey | 		if len(TimeFormat) == 0 { | ||||||
| 		TestTimeFormat, _ := time.Parse(TimeFormat, TimeFormat) | 			TimeFormat = timeFormatKey | ||||||
| 		if TestTimeFormat.Format(time.RFC3339) != "2006-01-02T15:04:05Z" { | 			TestTimeFormat, _ := time.Parse(TimeFormat, TimeFormat) | ||||||
| 			log.Fatal("Can't create time properly, please check your time format has 2006, 01, 02, 15, 04 and 05") | 			if TestTimeFormat.Format(time.RFC3339) != "2006-01-02T15:04:05Z" { | ||||||
|  | 				log.Fatal("Can't create time properly, please check your time format has 2006, 01, 02, 15, 04 and 05") | ||||||
|  | 			} | ||||||
|  | 			log.Trace("Custom TimeFormat: %s", TimeFormat) | ||||||
| 		} | 		} | ||||||
| 		log.Trace("Custom TimeFormat: %s", TimeFormat) | 	} | ||||||
|  | 
 | ||||||
|  | 	zone := Cfg.Section("time").Key("DEFAULT_UI_LOCATION").String() | ||||||
|  | 	if zone != "" { | ||||||
|  | 		DefaultUILocation, err = time.LoadLocation(zone) | ||||||
|  | 		if err != nil { | ||||||
|  | 			log.Fatal("Load time zone failed: %v", err) | ||||||
|  | 		} else { | ||||||
|  | 			log.Info("Default UI Location is %v", zone) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	if DefaultUILocation == nil { | ||||||
|  | 		DefaultUILocation = time.Local | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	RunUser = Cfg.Section("").Key("RUN_USER").MustString(user.CurrentUsername()) | 	RunUser = Cfg.Section("").Key("RUN_USER").MustString(user.CurrentUsername()) | ||||||
|  |  | ||||||
|  | @ -20,13 +20,13 @@ import ( | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"code.gitea.io/gitea/modules/util" |  | ||||||
| 
 |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	"code.gitea.io/gitea/modules/base" | 	"code.gitea.io/gitea/modules/base" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/markup" | 	"code.gitea.io/gitea/modules/markup" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
|  | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
|  | 	"code.gitea.io/gitea/modules/util" | ||||||
| 
 | 
 | ||||||
| 	"gopkg.in/editorconfig/editorconfig-core-go.v1" | 	"gopkg.in/editorconfig/editorconfig-core-go.v1" | ||||||
| ) | ) | ||||||
|  | @ -74,9 +74,9 @@ func NewFuncMap() []template.FuncMap { | ||||||
| 		"Safe":          Safe, | 		"Safe":          Safe, | ||||||
| 		"SafeJS":        SafeJS, | 		"SafeJS":        SafeJS, | ||||||
| 		"Str2html":      Str2html, | 		"Str2html":      Str2html, | ||||||
| 		"TimeSince":     base.TimeSince, | 		"TimeSince":     timeutil.TimeSince, | ||||||
| 		"TimeSinceUnix": base.TimeSinceUnix, | 		"TimeSinceUnix": timeutil.TimeSinceUnix, | ||||||
| 		"RawTimeSince":  base.RawTimeSince, | 		"RawTimeSince":  timeutil.RawTimeSince, | ||||||
| 		"FileSize":      base.FileSize, | 		"FileSize":      base.FileSize, | ||||||
| 		"Subtract":      base.Subtract, | 		"Subtract":      base.Subtract, | ||||||
| 		"EntryIcon":     base.EntryIcon, | 		"EntryIcon":     base.EntryIcon, | ||||||
|  |  | ||||||
							
								
								
									
										36
									
								
								modules/timeutil/language.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								modules/timeutil/language.go
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,36 @@ | ||||||
|  | // Copyright 2019 The Gitea Authors. All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a MIT-style
 | ||||||
|  | // license that can be found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | package timeutil | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"time" | ||||||
|  | 
 | ||||||
|  | 	"code.gitea.io/gitea/modules/setting" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | var ( | ||||||
|  | 	langTimeFormats = map[string]string{ | ||||||
|  | 		"zh-CN": "2006年01月02日 15时04分05秒", | ||||||
|  | 		"en-US": time.RFC1123, | ||||||
|  | 		"lv-LV": "02.01.2006. 15:04:05", | ||||||
|  | 	} | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // GetLangTimeFormat represents the default time format for the language
 | ||||||
|  | func GetLangTimeFormat(lang string) string { | ||||||
|  | 	return langTimeFormats[lang] | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // GetTimeFormat represents the
 | ||||||
|  | func GetTimeFormat(lang string) string { | ||||||
|  | 	if setting.TimeFormat == "" { | ||||||
|  | 		format := GetLangTimeFormat(lang) | ||||||
|  | 		if format == "" { | ||||||
|  | 			format = time.RFC1123 | ||||||
|  | 		} | ||||||
|  | 		return format | ||||||
|  | 	} | ||||||
|  | 	return setting.TimeFormat | ||||||
|  | } | ||||||
							
								
								
									
										164
									
								
								modules/timeutil/since.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										164
									
								
								modules/timeutil/since.go
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,164 @@ | ||||||
|  | // Copyright 2019 The Gitea Authors. All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a MIT-style
 | ||||||
|  | // license that can be found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | package timeutil | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"html/template" | ||||||
|  | 	"strings" | ||||||
|  | 	"time" | ||||||
|  | 
 | ||||||
|  | 	"code.gitea.io/gitea/modules/setting" | ||||||
|  | 
 | ||||||
|  | 	"github.com/Unknwon/i18n" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Seconds-based time units
 | ||||||
|  | const ( | ||||||
|  | 	Minute = 60 | ||||||
|  | 	Hour   = 60 * Minute | ||||||
|  | 	Day    = 24 * Hour | ||||||
|  | 	Week   = 7 * Day | ||||||
|  | 	Month  = 30 * Day | ||||||
|  | 	Year   = 12 * Month | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func computeTimeDiff(diff int64, lang string) (int64, string) { | ||||||
|  | 	diffStr := "" | ||||||
|  | 	switch { | ||||||
|  | 	case diff <= 0: | ||||||
|  | 		diff = 0 | ||||||
|  | 		diffStr = i18n.Tr(lang, "tool.now") | ||||||
|  | 	case diff < 2: | ||||||
|  | 		diff = 0 | ||||||
|  | 		diffStr = i18n.Tr(lang, "tool.1s") | ||||||
|  | 	case diff < 1*Minute: | ||||||
|  | 		diffStr = i18n.Tr(lang, "tool.seconds", diff) | ||||||
|  | 		diff = 0 | ||||||
|  | 
 | ||||||
|  | 	case diff < 2*Minute: | ||||||
|  | 		diff -= 1 * Minute | ||||||
|  | 		diffStr = i18n.Tr(lang, "tool.1m") | ||||||
|  | 	case diff < 1*Hour: | ||||||
|  | 		diffStr = i18n.Tr(lang, "tool.minutes", diff/Minute) | ||||||
|  | 		diff -= diff / Minute * Minute | ||||||
|  | 
 | ||||||
|  | 	case diff < 2*Hour: | ||||||
|  | 		diff -= 1 * Hour | ||||||
|  | 		diffStr = i18n.Tr(lang, "tool.1h") | ||||||
|  | 	case diff < 1*Day: | ||||||
|  | 		diffStr = i18n.Tr(lang, "tool.hours", diff/Hour) | ||||||
|  | 		diff -= diff / Hour * Hour | ||||||
|  | 
 | ||||||
|  | 	case diff < 2*Day: | ||||||
|  | 		diff -= 1 * Day | ||||||
|  | 		diffStr = i18n.Tr(lang, "tool.1d") | ||||||
|  | 	case diff < 1*Week: | ||||||
|  | 		diffStr = i18n.Tr(lang, "tool.days", diff/Day) | ||||||
|  | 		diff -= diff / Day * Day | ||||||
|  | 
 | ||||||
|  | 	case diff < 2*Week: | ||||||
|  | 		diff -= 1 * Week | ||||||
|  | 		diffStr = i18n.Tr(lang, "tool.1w") | ||||||
|  | 	case diff < 1*Month: | ||||||
|  | 		diffStr = i18n.Tr(lang, "tool.weeks", diff/Week) | ||||||
|  | 		diff -= diff / Week * Week | ||||||
|  | 
 | ||||||
|  | 	case diff < 2*Month: | ||||||
|  | 		diff -= 1 * Month | ||||||
|  | 		diffStr = i18n.Tr(lang, "tool.1mon") | ||||||
|  | 	case diff < 1*Year: | ||||||
|  | 		diffStr = i18n.Tr(lang, "tool.months", diff/Month) | ||||||
|  | 		diff -= diff / Month * Month | ||||||
|  | 
 | ||||||
|  | 	case diff < 2*Year: | ||||||
|  | 		diff -= 1 * Year | ||||||
|  | 		diffStr = i18n.Tr(lang, "tool.1y") | ||||||
|  | 	default: | ||||||
|  | 		diffStr = i18n.Tr(lang, "tool.years", diff/Year) | ||||||
|  | 		diff -= (diff / Year) * Year | ||||||
|  | 	} | ||||||
|  | 	return diff, diffStr | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // MinutesToFriendly returns a user friendly string with number of minutes
 | ||||||
|  | // converted to hours and minutes.
 | ||||||
|  | func MinutesToFriendly(minutes int, lang string) string { | ||||||
|  | 	duration := time.Duration(minutes) * time.Minute | ||||||
|  | 	return TimeSincePro(time.Now().Add(-duration), lang) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // TimeSincePro calculates the time interval and generate full user-friendly string.
 | ||||||
|  | func TimeSincePro(then time.Time, lang string) string { | ||||||
|  | 	return timeSincePro(then, time.Now(), lang) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func timeSincePro(then, now time.Time, lang string) string { | ||||||
|  | 	diff := now.Unix() - then.Unix() | ||||||
|  | 
 | ||||||
|  | 	if then.After(now) { | ||||||
|  | 		return i18n.Tr(lang, "tool.future") | ||||||
|  | 	} | ||||||
|  | 	if diff == 0 { | ||||||
|  | 		return i18n.Tr(lang, "tool.now") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var timeStr, diffStr string | ||||||
|  | 	for { | ||||||
|  | 		if diff == 0 { | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		diff, diffStr = computeTimeDiff(diff, lang) | ||||||
|  | 		timeStr += ", " + diffStr | ||||||
|  | 	} | ||||||
|  | 	return strings.TrimPrefix(timeStr, ", ") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 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 - then | ||||||
|  | 	if then > now { | ||||||
|  | 		lbl = "tool.from_now" | ||||||
|  | 		diff = then - now | ||||||
|  | 	} | ||||||
|  | 	if diff <= 0 { | ||||||
|  | 		return i18n.Tr(lang, "tool.now") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	_, diffStr := computeTimeDiff(diff, lang) | ||||||
|  | 	return i18n.Tr(lang, lbl, diffStr) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // RawTimeSince retrieves i18n key of time since t
 | ||||||
|  | func RawTimeSince(t time.Time, lang string) string { | ||||||
|  | 	return timeSince(t, time.Now(), lang) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // TimeSince calculates the time interval and generate user-friendly string.
 | ||||||
|  | func TimeSince(then time.Time, lang string) template.HTML { | ||||||
|  | 	return htmlTimeSince(then, time.Now(), lang) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func htmlTimeSince(then, now time.Time, lang string) template.HTML { | ||||||
|  | 	return template.HTML(fmt.Sprintf(`<span class="time-since" title="%s">%s</span>`, | ||||||
|  | 		then.In(setting.DefaultUILocation).Format(GetTimeFormat(lang)), | ||||||
|  | 		timeSince(then, now, lang))) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // TimeSinceUnix calculates the time interval and generate user-friendly string.
 | ||||||
|  | func TimeSinceUnix(then TimeStamp, lang string) template.HTML { | ||||||
|  | 	return htmlTimeSinceUnix(then, TimeStamp(time.Now().Unix()), lang) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func htmlTimeSinceUnix(then, now TimeStamp, lang string) template.HTML { | ||||||
|  | 	return template.HTML(fmt.Sprintf(`<span class="time-since" title="%s">%s</span>`, | ||||||
|  | 		then.FormatInLocation(GetTimeFormat(lang), setting.DefaultUILocation), | ||||||
|  | 		timeSinceUnix(int64(then), int64(now), lang))) | ||||||
|  | } | ||||||
							
								
								
									
										163
									
								
								modules/timeutil/since_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								modules/timeutil/since_test.go
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,163 @@ | ||||||
|  | // Copyright 2019 The Gitea Authors. All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a MIT-style
 | ||||||
|  | // license that can be found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | package timeutil | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"os" | ||||||
|  | 	"testing" | ||||||
|  | 	"time" | ||||||
|  | 
 | ||||||
|  | 	"code.gitea.io/gitea/modules/setting" | ||||||
|  | 
 | ||||||
|  | 	"github.com/Unknwon/i18n" | ||||||
|  | 	macaroni18n "github.com/go-macaron/i18n" | ||||||
|  | 	"github.com/stretchr/testify/assert" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | var BaseDate time.Time | ||||||
|  | 
 | ||||||
|  | // time durations
 | ||||||
|  | const ( | ||||||
|  | 	DayDur   = 24 * time.Hour | ||||||
|  | 	WeekDur  = 7 * DayDur | ||||||
|  | 	MonthDur = 30 * DayDur | ||||||
|  | 	YearDur  = 12 * MonthDur | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func TestMain(m *testing.M) { | ||||||
|  | 	// setup
 | ||||||
|  | 	macaroni18n.I18n(macaroni18n.Options{ | ||||||
|  | 		Directory:   "../../options/locale/", | ||||||
|  | 		DefaultLang: "en-US", | ||||||
|  | 		Langs:       []string{"en-US"}, | ||||||
|  | 		Names:       []string{"english"}, | ||||||
|  | 	}) | ||||||
|  | 	BaseDate = time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC) | ||||||
|  | 
 | ||||||
|  | 	// run the tests
 | ||||||
|  | 	retVal := m.Run() | ||||||
|  | 
 | ||||||
|  | 	os.Exit(retVal) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestTimeSince(t *testing.T) { | ||||||
|  | 	assert.Equal(t, "now", timeSince(BaseDate, BaseDate, "en")) | ||||||
|  | 
 | ||||||
|  | 	// test that each diff in `diffs` yields the expected string
 | ||||||
|  | 	test := func(expected string, diffs ...time.Duration) { | ||||||
|  | 		for _, diff := range diffs { | ||||||
|  | 			actual := timeSince(BaseDate, BaseDate.Add(diff), "en") | ||||||
|  | 			assert.Equal(t, i18n.Tr("en", "tool.ago", expected), actual) | ||||||
|  | 			actual = timeSince(BaseDate.Add(diff), BaseDate, "en") | ||||||
|  | 			assert.Equal(t, i18n.Tr("en", "tool.from_now", expected), actual) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	test("1 second", time.Second, time.Second+50*time.Millisecond) | ||||||
|  | 	test("2 seconds", 2*time.Second, 2*time.Second+50*time.Millisecond) | ||||||
|  | 	test("1 minute", time.Minute, time.Minute+30*time.Second) | ||||||
|  | 	test("2 minutes", 2*time.Minute, 2*time.Minute+30*time.Second) | ||||||
|  | 	test("1 hour", time.Hour, time.Hour+30*time.Minute) | ||||||
|  | 	test("2 hours", 2*time.Hour, 2*time.Hour+30*time.Minute) | ||||||
|  | 	test("1 day", DayDur, DayDur+12*time.Hour) | ||||||
|  | 	test("2 days", 2*DayDur, 2*DayDur+12*time.Hour) | ||||||
|  | 	test("1 week", WeekDur, WeekDur+3*DayDur) | ||||||
|  | 	test("2 weeks", 2*WeekDur, 2*WeekDur+3*DayDur) | ||||||
|  | 	test("1 month", MonthDur, MonthDur+15*DayDur) | ||||||
|  | 	test("2 months", 2*MonthDur, 2*MonthDur+15*DayDur) | ||||||
|  | 	test("1 year", YearDur, YearDur+6*MonthDur) | ||||||
|  | 	test("2 years", 2*YearDur, 2*YearDur+6*MonthDur) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestTimeSincePro(t *testing.T) { | ||||||
|  | 	assert.Equal(t, "now", timeSincePro(BaseDate, BaseDate, "en")) | ||||||
|  | 
 | ||||||
|  | 	// test that a difference of `diff` yields the expected string
 | ||||||
|  | 	test := func(expected string, diff time.Duration) { | ||||||
|  | 		actual := timeSincePro(BaseDate, BaseDate.Add(diff), "en") | ||||||
|  | 		assert.Equal(t, expected, actual) | ||||||
|  | 		assert.Equal(t, "future", timeSincePro(BaseDate.Add(diff), BaseDate, "en")) | ||||||
|  | 	} | ||||||
|  | 	test("1 second", time.Second) | ||||||
|  | 	test("2 seconds", 2*time.Second) | ||||||
|  | 	test("1 minute", time.Minute) | ||||||
|  | 	test("1 minute, 1 second", time.Minute+time.Second) | ||||||
|  | 	test("1 minute, 59 seconds", time.Minute+59*time.Second) | ||||||
|  | 	test("2 minutes", 2*time.Minute) | ||||||
|  | 	test("1 hour", time.Hour) | ||||||
|  | 	test("1 hour, 1 second", time.Hour+time.Second) | ||||||
|  | 	test("1 hour, 59 minutes, 59 seconds", time.Hour+59*time.Minute+59*time.Second) | ||||||
|  | 	test("2 hours", 2*time.Hour) | ||||||
|  | 	test("1 day", DayDur) | ||||||
|  | 	test("1 day, 23 hours, 59 minutes, 59 seconds", | ||||||
|  | 		DayDur+23*time.Hour+59*time.Minute+59*time.Second) | ||||||
|  | 	test("2 days", 2*DayDur) | ||||||
|  | 	test("1 week", WeekDur) | ||||||
|  | 	test("2 weeks", 2*WeekDur) | ||||||
|  | 	test("1 month", MonthDur) | ||||||
|  | 	test("3 months", 3*MonthDur) | ||||||
|  | 	test("1 year", YearDur) | ||||||
|  | 	test("2 years, 3 months, 1 week, 2 days, 4 hours, 12 minutes, 17 seconds", | ||||||
|  | 		2*YearDur+3*MonthDur+WeekDur+2*DayDur+4*time.Hour+ | ||||||
|  | 			12*time.Minute+17*time.Second) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestHtmlTimeSince(t *testing.T) { | ||||||
|  | 	setting.TimeFormat = time.UnixDate | ||||||
|  | 	setting.DefaultUILocation = time.UTC | ||||||
|  | 	// test that `diff` yields a result containing `expected`
 | ||||||
|  | 	test := func(expected string, diff time.Duration) { | ||||||
|  | 		actual := htmlTimeSince(BaseDate, BaseDate.Add(diff), "en") | ||||||
|  | 		assert.Contains(t, actual, `title="Sat Jan  1 00:00:00 UTC 2000"`) | ||||||
|  | 		assert.Contains(t, actual, expected) | ||||||
|  | 	} | ||||||
|  | 	test("1 second", time.Second) | ||||||
|  | 	test("3 minutes", 3*time.Minute+5*time.Second) | ||||||
|  | 	test("1 day", DayDur+18*time.Hour) | ||||||
|  | 	test("1 week", WeekDur+6*DayDur) | ||||||
|  | 	test("3 months", 3*MonthDur+3*WeekDur) | ||||||
|  | 	test("2 years", 2*YearDur) | ||||||
|  | 	test("3 years", 3*YearDur+11*MonthDur+4*WeekDur) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestComputeTimeDiff(t *testing.T) { | ||||||
|  | 	// test that for each offset in offsets,
 | ||||||
|  | 	// computeTimeDiff(base + offset) == (offset, str)
 | ||||||
|  | 	test := func(base int64, str string, offsets ...int64) { | ||||||
|  | 		for _, offset := range offsets { | ||||||
|  | 			diff, diffStr := computeTimeDiff(base+offset, "en") | ||||||
|  | 			assert.Equal(t, offset, diff) | ||||||
|  | 			assert.Equal(t, str, diffStr) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	test(0, "now", 0) | ||||||
|  | 	test(1, "1 second", 0) | ||||||
|  | 	test(2, "2 seconds", 0) | ||||||
|  | 	test(Minute, "1 minute", 0, 1, 30, Minute-1) | ||||||
|  | 	test(2*Minute, "2 minutes", 0, Minute-1) | ||||||
|  | 	test(Hour, "1 hour", 0, 1, Hour-1) | ||||||
|  | 	test(5*Hour, "5 hours", 0, Hour-1) | ||||||
|  | 	test(Day, "1 day", 0, 1, Day-1) | ||||||
|  | 	test(5*Day, "5 days", 0, Day-1) | ||||||
|  | 	test(Week, "1 week", 0, 1, Week-1) | ||||||
|  | 	test(3*Week, "3 weeks", 0, 4*Day+25000) | ||||||
|  | 	test(Month, "1 month", 0, 1, Month-1) | ||||||
|  | 	test(10*Month, "10 months", 0, Month-1) | ||||||
|  | 	test(Year, "1 year", 0, Year-1) | ||||||
|  | 	test(3*Year, "3 years", 0, Year-1) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestMinutesToFriendly(t *testing.T) { | ||||||
|  | 	// test that a number of minutes yields the expected string
 | ||||||
|  | 	test := func(expected string, minutes int) { | ||||||
|  | 		actual := MinutesToFriendly(minutes, "en") | ||||||
|  | 		assert.Equal(t, expected, actual) | ||||||
|  | 	} | ||||||
|  | 	test("1 minute", 1) | ||||||
|  | 	test("2 minutes", 2) | ||||||
|  | 	test("1 hour", 60) | ||||||
|  | 	test("1 hour, 1 minute", 61) | ||||||
|  | 	test("1 hour, 2 minutes", 62) | ||||||
|  | 	test("2 hours", 120) | ||||||
|  | } | ||||||
|  | @ -2,7 +2,7 @@ | ||||||
| // Use of this source code is governed by a MIT-style
 | // Use of this source code is governed by a MIT-style
 | ||||||
| // license that can be found in the LICENSE file.
 | // license that can be found in the LICENSE file.
 | ||||||
| 
 | 
 | ||||||
| package util | package timeutil | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"time" | 	"time" | ||||||
|  | @ -35,19 +35,34 @@ func (ts TimeStamp) Year() int { | ||||||
| 
 | 
 | ||||||
| // AsTime convert timestamp as time.Time in Local locale
 | // AsTime convert timestamp as time.Time in Local locale
 | ||||||
| func (ts TimeStamp) AsTime() (tm time.Time) { | func (ts TimeStamp) AsTime() (tm time.Time) { | ||||||
| 	tm = time.Unix(int64(ts), 0).In(setting.UILocation) | 	return ts.AsTimeInLocation(setting.DefaultUILocation) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // AsTimeInLocation convert timestamp as time.Time in Local locale
 | ||||||
|  | func (ts TimeStamp) AsTimeInLocation(loc *time.Location) (tm time.Time) { | ||||||
|  | 	tm = time.Unix(int64(ts), 0).In(loc) | ||||||
| 	return | 	return | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // AsTimePtr convert timestamp as *time.Time in Local locale
 | // AsTimePtr convert timestamp as *time.Time in Local locale
 | ||||||
| func (ts TimeStamp) AsTimePtr() *time.Time { | func (ts TimeStamp) AsTimePtr() *time.Time { | ||||||
| 	tm := time.Unix(int64(ts), 0).In(setting.UILocation) | 	return ts.AsTimePtrInLocation(setting.DefaultUILocation) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // AsTimePtrInLocation convert timestamp as *time.Time in customize location
 | ||||||
|  | func (ts TimeStamp) AsTimePtrInLocation(loc *time.Location) *time.Time { | ||||||
|  | 	tm := time.Unix(int64(ts), 0).In(loc) | ||||||
| 	return &tm | 	return &tm | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Format formats timestamp as
 | // Format formats timestamp as given format
 | ||||||
| func (ts TimeStamp) Format(f string) string { | func (ts TimeStamp) Format(f string) string { | ||||||
| 	return ts.AsTime().Format(f) | 	return ts.FormatInLocation(f, setting.DefaultUILocation) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // FormatInLocation formats timestamp as given format with spiecific location
 | ||||||
|  | func (ts TimeStamp) FormatInLocation(f string, loc *time.Location) string { | ||||||
|  | 	return ts.AsTimeInLocation(loc).Format(f) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // FormatLong formats as RFC1123Z
 | // FormatLong formats as RFC1123Z
 | ||||||
|  | @ -62,5 +77,5 @@ func (ts TimeStamp) FormatShort() string { | ||||||
| 
 | 
 | ||||||
| // IsZero is zero time
 | // IsZero is zero time
 | ||||||
| func (ts TimeStamp) IsZero() bool { | func (ts TimeStamp) IsZero() bool { | ||||||
| 	return ts.AsTime().IsZero() | 	return ts.AsTimeInLocation(time.Local).IsZero() | ||||||
| } | } | ||||||
|  | @ -1959,10 +1959,6 @@ $(document).ready(function () { | ||||||
| 
 | 
 | ||||||
|     // Show exact time
 |     // Show exact time
 | ||||||
|     $('.time-since').each(function () { |     $('.time-since').each(function () { | ||||||
|         const time = new Date($(this).attr('title')) |  | ||||||
|         if (!isNaN(time)){ |  | ||||||
|             $(this).attr('title', time.toLocaleString()) |  | ||||||
|         } |  | ||||||
|         $(this).addClass('poping up').attr('data-content', $(this).attr('title')).attr('data-variation', 'inverted tiny').attr('title', ''); |         $(this).addClass('poping up').attr('data-content', $(this).attr('title')).attr('data-variation', 'inverted tiny').attr('title', ''); | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -24,6 +24,7 @@ import ( | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/process" | 	"code.gitea.io/gitea/modules/process" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
|  | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| const ( | const ( | ||||||
|  | @ -78,7 +79,7 @@ var sysStatus struct { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func updateSystemStatus() { | func updateSystemStatus() { | ||||||
| 	sysStatus.Uptime = base.TimeSincePro(startTime, "en") | 	sysStatus.Uptime = timeutil.TimeSincePro(startTime, "en") | ||||||
| 
 | 
 | ||||||
| 	m := new(runtime.MemStats) | 	m := new(runtime.MemStats) | ||||||
| 	runtime.ReadMemStats(m) | 	runtime.ReadMemStats(m) | ||||||
|  |  | ||||||
|  | @ -16,6 +16,7 @@ import ( | ||||||
| 	issue_indexer "code.gitea.io/gitea/modules/indexer/issues" | 	issue_indexer "code.gitea.io/gitea/modules/indexer/issues" | ||||||
| 	"code.gitea.io/gitea/modules/notification" | 	"code.gitea.io/gitea/modules/notification" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
|  | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/util" | ||||||
| 
 | 
 | ||||||
| 	api "code.gitea.io/gitea/modules/structs" | 	api "code.gitea.io/gitea/modules/structs" | ||||||
|  | @ -183,9 +184,9 @@ func CreateIssue(ctx *context.APIContext, form api.CreateIssueOption) { | ||||||
| 	//   "201":
 | 	//   "201":
 | ||||||
| 	//     "$ref": "#/responses/Issue"
 | 	//     "$ref": "#/responses/Issue"
 | ||||||
| 
 | 
 | ||||||
| 	var deadlineUnix util.TimeStamp | 	var deadlineUnix timeutil.TimeStamp | ||||||
| 	if form.Deadline != nil && ctx.Repo.CanWrite(models.UnitTypeIssues) { | 	if form.Deadline != nil && ctx.Repo.CanWrite(models.UnitTypeIssues) { | ||||||
| 		deadlineUnix = util.TimeStamp(form.Deadline.Unix()) | 		deadlineUnix = timeutil.TimeStamp(form.Deadline.Unix()) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	issue := &models.Issue{ | 	issue := &models.Issue{ | ||||||
|  | @ -310,9 +311,9 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Update the deadline
 | 	// Update the deadline
 | ||||||
| 	var deadlineUnix util.TimeStamp | 	var deadlineUnix timeutil.TimeStamp | ||||||
| 	if form.Deadline != nil && !form.Deadline.IsZero() && ctx.Repo.CanWrite(models.UnitTypeIssues) { | 	if form.Deadline != nil && !form.Deadline.IsZero() && ctx.Repo.CanWrite(models.UnitTypeIssues) { | ||||||
| 		deadlineUnix = util.TimeStamp(form.Deadline.Unix()) | 		deadlineUnix = timeutil.TimeStamp(form.Deadline.Unix()) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if err := models.UpdateIssueDeadline(issue, deadlineUnix, ctx.User); err != nil { | 	if err := models.UpdateIssueDeadline(issue, deadlineUnix, ctx.User); err != nil { | ||||||
|  | @ -430,12 +431,12 @@ func UpdateIssueDeadline(ctx *context.APIContext, form api.EditDeadlineOption) { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	var deadlineUnix util.TimeStamp | 	var deadlineUnix timeutil.TimeStamp | ||||||
| 	var deadline time.Time | 	var deadline time.Time | ||||||
| 	if form.Deadline != nil && !form.Deadline.IsZero() { | 	if form.Deadline != nil && !form.Deadline.IsZero() { | ||||||
| 		deadline = time.Date(form.Deadline.Year(), form.Deadline.Month(), form.Deadline.Day(), | 		deadline = time.Date(form.Deadline.Year(), form.Deadline.Month(), form.Deadline.Day(), | ||||||
| 			23, 59, 59, 0, form.Deadline.Location()) | 			23, 59, 59, 0, form.Deadline.Location()) | ||||||
| 		deadlineUnix = util.TimeStamp(deadline.Unix()) | 		deadlineUnix = timeutil.TimeStamp(deadline.Unix()) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if err := models.UpdateIssueDeadline(issue, deadlineUnix, ctx.User); err != nil { | 	if err := models.UpdateIssueDeadline(issue, deadlineUnix, ctx.User); err != nil { | ||||||
|  |  | ||||||
|  | @ -9,9 +9,8 @@ import ( | ||||||
| 
 | 
 | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| 	"code.gitea.io/gitea/modules/util" |  | ||||||
| 
 |  | ||||||
| 	api "code.gitea.io/gitea/modules/structs" | 	api "code.gitea.io/gitea/modules/structs" | ||||||
|  | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // ListMilestones list milestones for a repository
 | // ListMilestones list milestones for a repository
 | ||||||
|  | @ -127,7 +126,7 @@ func CreateMilestone(ctx *context.APIContext, form api.CreateMilestoneOption) { | ||||||
| 		RepoID:       ctx.Repo.Repository.ID, | 		RepoID:       ctx.Repo.Repository.ID, | ||||||
| 		Name:         form.Title, | 		Name:         form.Title, | ||||||
| 		Content:      form.Description, | 		Content:      form.Description, | ||||||
| 		DeadlineUnix: util.TimeStamp(form.Deadline.Unix()), | 		DeadlineUnix: timeutil.TimeStamp(form.Deadline.Unix()), | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if err := models.NewMilestone(milestone); err != nil { | 	if err := models.NewMilestone(milestone); err != nil { | ||||||
|  | @ -187,7 +186,7 @@ func EditMilestone(ctx *context.APIContext, form api.EditMilestoneOption) { | ||||||
| 		milestone.Content = *form.Description | 		milestone.Content = *form.Description | ||||||
| 	} | 	} | ||||||
| 	if form.Deadline != nil && !form.Deadline.IsZero() { | 	if form.Deadline != nil && !form.Deadline.IsZero() { | ||||||
| 		milestone.DeadlineUnix = util.TimeStamp(form.Deadline.Unix()) | 		milestone.DeadlineUnix = timeutil.TimeStamp(form.Deadline.Unix()) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if err := models.UpdateMilestone(milestone); err != nil { | 	if err := models.UpdateMilestone(milestone); err != nil { | ||||||
|  |  | ||||||
|  | @ -17,7 +17,7 @@ import ( | ||||||
| 	"code.gitea.io/gitea/modules/notification" | 	"code.gitea.io/gitea/modules/notification" | ||||||
| 	"code.gitea.io/gitea/modules/pull" | 	"code.gitea.io/gitea/modules/pull" | ||||||
| 	api "code.gitea.io/gitea/modules/structs" | 	api "code.gitea.io/gitea/modules/structs" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // ListPullRequests returns a list of all PRs
 | // ListPullRequests returns a list of all PRs
 | ||||||
|  | @ -247,9 +247,9 @@ func CreatePullRequest(ctx *context.APIContext, form api.CreatePullRequestOption | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	var deadlineUnix util.TimeStamp | 	var deadlineUnix timeutil.TimeStamp | ||||||
| 	if form.Deadline != nil { | 	if form.Deadline != nil { | ||||||
| 		deadlineUnix = util.TimeStamp(form.Deadline.Unix()) | 		deadlineUnix = timeutil.TimeStamp(form.Deadline.Unix()) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	maxIndex, err := models.GetMaxIndexOfIssue(repo.ID) | 	maxIndex, err := models.GetMaxIndexOfIssue(repo.ID) | ||||||
|  | @ -375,9 +375,9 @@ func EditPullRequest(ctx *context.APIContext, form api.EditPullRequestOption) { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Update Deadline
 | 	// Update Deadline
 | ||||||
| 	var deadlineUnix util.TimeStamp | 	var deadlineUnix timeutil.TimeStamp | ||||||
| 	if form.Deadline != nil && !form.Deadline.IsZero() { | 	if form.Deadline != nil && !form.Deadline.IsZero() { | ||||||
| 		deadlineUnix = util.TimeStamp(form.Deadline.Unix()) | 		deadlineUnix = timeutil.TimeStamp(form.Deadline.Unix()) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if err := models.UpdateIssueDeadline(issue, deadlineUnix, ctx.User); err != nil { | 	if err := models.UpdateIssueDeadline(issue, deadlineUnix, ctx.User); err != nil { | ||||||
|  |  | ||||||
|  | @ -9,6 +9,7 @@ import ( | ||||||
| 	"code.gitea.io/gitea/modules/base" | 	"code.gitea.io/gitea/modules/base" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
|  | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // TemplatePreview render for previewing the indicated template
 | // TemplatePreview render for previewing the indicated template
 | ||||||
|  | @ -18,8 +19,8 @@ func TemplatePreview(ctx *context.Context) { | ||||||
| 	ctx.Data["AppVer"] = setting.AppVer | 	ctx.Data["AppVer"] = setting.AppVer | ||||||
| 	ctx.Data["AppUrl"] = setting.AppURL | 	ctx.Data["AppUrl"] = setting.AppURL | ||||||
| 	ctx.Data["Code"] = "2014031910370000009fff6782aadb2162b4a997acb69d4400888e0b9274657374" | 	ctx.Data["Code"] = "2014031910370000009fff6782aadb2162b4a997acb69d4400888e0b9274657374" | ||||||
| 	ctx.Data["ActiveCodeLives"] = base.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language()) | 	ctx.Data["ActiveCodeLives"] = timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language()) | ||||||
| 	ctx.Data["ResetPwdCodeLives"] = base.MinutesToFriendly(setting.Service.ResetPwdCodeLives, ctx.Locale.Language()) | 	ctx.Data["ResetPwdCodeLives"] = timeutil.MinutesToFriendly(setting.Service.ResetPwdCodeLives, ctx.Locale.Language()) | ||||||
| 	ctx.Data["CurDbValue"] = "" | 	ctx.Data["CurDbValue"] = "" | ||||||
| 
 | 
 | ||||||
| 	ctx.HTML(200, base.TplName(ctx.Params("*"))) | 	ctx.HTML(200, base.TplName(ctx.Params("*"))) | ||||||
|  |  | ||||||
|  | @ -7,7 +7,7 @@ package private | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 
 | 
 | ||||||
| 	macaron "gopkg.in/macaron.v1" | 	macaron "gopkg.in/macaron.v1" | ||||||
| ) | ) | ||||||
|  | @ -34,7 +34,7 @@ func UpdatePublicKeyInRepo(ctx *macaron.Context) { | ||||||
| 		}) | 		}) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	deployKey.UpdatedUnix = util.TimeStampNow() | 	deployKey.UpdatedUnix = timeutil.TimeStampNow() | ||||||
| 	if err = models.UpdateDeployKeyCols(deployKey, "updated_unix"); err != nil { | 	if err = models.UpdateDeployKeyCols(deployKey, "updated_unix"); err != nil { | ||||||
| 		ctx.JSON(500, map[string]interface{}{ | 		ctx.JSON(500, map[string]interface{}{ | ||||||
| 			"err": err.Error(), | 			"err": err.Error(), | ||||||
|  |  | ||||||
|  | @ -14,7 +14,6 @@ import ( | ||||||
| 	"strings" | 	"strings" | ||||||
| 
 | 
 | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 
 |  | ||||||
| 	"code.gitea.io/gitea/modules/base" | 	"code.gitea.io/gitea/modules/base" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| 	"code.gitea.io/gitea/modules/git" | 	"code.gitea.io/gitea/modules/git" | ||||||
|  | @ -22,7 +21,7 @@ import ( | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/markup" | 	"code.gitea.io/gitea/modules/markup" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| const ( | const ( | ||||||
|  | @ -212,7 +211,7 @@ func renderBlame(ctx *context.Context, blameParts []git.BlamePart, commitNames m | ||||||
| 			if index == 0 { | 			if index == 0 { | ||||||
| 				// User avatar image
 | 				// User avatar image
 | ||||||
| 				avatar := "" | 				avatar := "" | ||||||
| 				commitSince := base.TimeSinceUnix(util.TimeStamp(commit.Author.When.Unix()), ctx.Data["Lang"].(string)) | 				commitSince := timeutil.TimeSinceUnix(timeutil.TimeStamp(commit.Author.When.Unix()), ctx.Data["Lang"].(string)) | ||||||
| 				if commit.User != nil { | 				if commit.User != nil { | ||||||
| 					authorName := commit.Author.Name | 					authorName := commit.Author.Name | ||||||
| 					if len(commit.User.FullName) > 0 { | 					if len(commit.User.FullName) > 0 { | ||||||
|  |  | ||||||
|  | @ -25,7 +25,7 @@ import ( | ||||||
| 	"code.gitea.io/gitea/modules/git" | 	"code.gitea.io/gitea/modules/git" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // HTTP implmentation git smart HTTP protocol
 | // HTTP implmentation git smart HTTP protocol
 | ||||||
|  | @ -203,7 +203,7 @@ func HTTP(ctx *context.Context) { | ||||||
| 						return | 						return | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 				token.UpdatedUnix = util.TimeStampNow() | 				token.UpdatedUnix = timeutil.TimeStampNow() | ||||||
| 				if err = models.UpdateAccessToken(token); err != nil { | 				if err = models.UpdateAccessToken(token); err != nil { | ||||||
| 					ctx.ServerError("UpdateAccessToken", err) | 					ctx.ServerError("UpdateAccessToken", err) | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
|  | @ -13,6 +13,7 @@ import ( | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| 	"code.gitea.io/gitea/modules/markup/markdown" | 	"code.gitea.io/gitea/modules/markup/markdown" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
|  | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/util" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -120,7 +121,7 @@ func NewMilestonePost(ctx *context.Context, form auth.CreateMilestoneForm) { | ||||||
| 		RepoID:       ctx.Repo.Repository.ID, | 		RepoID:       ctx.Repo.Repository.ID, | ||||||
| 		Name:         form.Title, | 		Name:         form.Title, | ||||||
| 		Content:      form.Content, | 		Content:      form.Content, | ||||||
| 		DeadlineUnix: util.TimeStamp(deadline.Unix()), | 		DeadlineUnix: timeutil.TimeStamp(deadline.Unix()), | ||||||
| 	}); err != nil { | 	}); err != nil { | ||||||
| 		ctx.ServerError("NewMilestone", err) | 		ctx.ServerError("NewMilestone", err) | ||||||
| 		return | 		return | ||||||
|  | @ -190,7 +191,7 @@ func EditMilestonePost(ctx *context.Context, form auth.CreateMilestoneForm) { | ||||||
| 	} | 	} | ||||||
| 	m.Name = form.Title | 	m.Name = form.Title | ||||||
| 	m.Content = form.Content | 	m.Content = form.Content | ||||||
| 	m.DeadlineUnix = util.TimeStamp(deadline.Unix()) | 	m.DeadlineUnix = timeutil.TimeStamp(deadline.Unix()) | ||||||
| 	if err = models.UpdateMilestone(m); err != nil { | 	if err = models.UpdateMilestone(m); err != nil { | ||||||
| 		ctx.ServerError("UpdateMilestone", err) | 		ctx.ServerError("UpdateMilestone", err) | ||||||
| 		return | 		return | ||||||
|  | @ -223,7 +224,7 @@ func ChangeMilestonStatus(ctx *context.Context) { | ||||||
| 		ctx.Redirect(ctx.Repo.RepoLink + "/milestones?state=open") | 		ctx.Redirect(ctx.Repo.RepoLink + "/milestones?state=open") | ||||||
| 	case "close": | 	case "close": | ||||||
| 		if !m.IsClosed { | 		if !m.IsClosed { | ||||||
| 			m.ClosedDateUnix = util.TimeStampNow() | 			m.ClosedDateUnix = timeutil.TimeStampNow() | ||||||
| 			if err = models.ChangeMilestoneStatus(m, true); err != nil { | 			if err = models.ChangeMilestoneStatus(m, true); err != nil { | ||||||
| 				ctx.ServerError("ChangeMilestoneStatus", err) | 				ctx.ServerError("ChangeMilestoneStatus", err) | ||||||
| 				return | 				return | ||||||
|  |  | ||||||
|  | @ -14,9 +14,6 @@ import ( | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"github.com/Unknwon/com" |  | ||||||
| 	"mvdan.cc/xurls/v2" |  | ||||||
| 
 |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	"code.gitea.io/gitea/modules/auth" | 	"code.gitea.io/gitea/modules/auth" | ||||||
| 	"code.gitea.io/gitea/modules/base" | 	"code.gitea.io/gitea/modules/base" | ||||||
|  | @ -24,9 +21,12 @@ import ( | ||||||
| 	"code.gitea.io/gitea/modules/git" | 	"code.gitea.io/gitea/modules/git" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 	"code.gitea.io/gitea/modules/validation" | 	"code.gitea.io/gitea/modules/validation" | ||||||
| 	"code.gitea.io/gitea/routers/utils" | 	"code.gitea.io/gitea/routers/utils" | ||||||
|  | 
 | ||||||
|  | 	"github.com/Unknwon/com" | ||||||
|  | 	"mvdan.cc/xurls/v2" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| const ( | const ( | ||||||
|  | @ -144,7 +144,7 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) { | ||||||
| 			ctx.Repo.Mirror.EnablePrune = form.EnablePrune | 			ctx.Repo.Mirror.EnablePrune = form.EnablePrune | ||||||
| 			ctx.Repo.Mirror.Interval = interval | 			ctx.Repo.Mirror.Interval = interval | ||||||
| 			if interval != 0 { | 			if interval != 0 { | ||||||
| 				ctx.Repo.Mirror.NextUpdateUnix = util.TimeStampNow().AddDuration(interval) | 				ctx.Repo.Mirror.NextUpdateUnix = timeutil.TimeStampNow().AddDuration(interval) | ||||||
| 			} else { | 			} else { | ||||||
| 				ctx.Repo.Mirror.NextUpdateUnix = 0 | 				ctx.Repo.Mirror.NextUpdateUnix = 0 | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|  | @ -19,6 +19,7 @@ import ( | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/markup" | 	"code.gitea.io/gitea/modules/markup" | ||||||
| 	"code.gitea.io/gitea/modules/markup/markdown" | 	"code.gitea.io/gitea/modules/markup/markdown" | ||||||
|  | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/util" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -58,7 +59,7 @@ func MustEnableWiki(ctx *context.Context) { | ||||||
| type PageMeta struct { | type PageMeta struct { | ||||||
| 	Name        string | 	Name        string | ||||||
| 	SubURL      string | 	SubURL      string | ||||||
| 	UpdatedUnix util.TimeStamp | 	UpdatedUnix timeutil.TimeStamp | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // findEntryForFile finds the tree entry for a target filepath.
 | // findEntryForFile finds the tree entry for a target filepath.
 | ||||||
|  | @ -413,7 +414,7 @@ func WikiPages(ctx *context.Context) { | ||||||
| 		pages = append(pages, PageMeta{ | 		pages = append(pages, PageMeta{ | ||||||
| 			Name:        wikiName, | 			Name:        wikiName, | ||||||
| 			SubURL:      models.WikiNameToSubURL(wikiName), | 			SubURL:      models.WikiNameToSubURL(wikiName), | ||||||
| 			UpdatedUnix: util.TimeStamp(c.Author.When.Unix()), | 			UpdatedUnix: timeutil.TimeStamp(c.Author.When.Unix()), | ||||||
| 		}) | 		}) | ||||||
| 	} | 	} | ||||||
| 	ctx.Data["Pages"] = pages | 	ctx.Data["Pages"] = pages | ||||||
|  |  | ||||||
|  | @ -19,6 +19,7 @@ import ( | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/recaptcha" | 	"code.gitea.io/gitea/modules/recaptcha" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
|  | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/util" | ||||||
| 
 | 
 | ||||||
| 	"github.com/go-macaron/captcha" | 	"github.com/go-macaron/captcha" | ||||||
|  | @ -950,7 +951,7 @@ func LinkAccountPostRegister(ctx *context.Context, cpt *captcha.Captcha, form au | ||||||
| 		models.SendActivateAccountMail(ctx.Context, u) | 		models.SendActivateAccountMail(ctx.Context, u) | ||||||
| 		ctx.Data["IsSendRegisterMail"] = true | 		ctx.Data["IsSendRegisterMail"] = true | ||||||
| 		ctx.Data["Email"] = u.Email | 		ctx.Data["Email"] = u.Email | ||||||
| 		ctx.Data["ActiveCodeLives"] = base.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language()) | 		ctx.Data["ActiveCodeLives"] = timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language()) | ||||||
| 		ctx.HTML(200, TplActivate) | 		ctx.HTML(200, TplActivate) | ||||||
| 
 | 
 | ||||||
| 		if err := ctx.Cache.Put("MailResendLimit_"+u.LowerName, u.LowerName, 180); err != nil { | 		if err := ctx.Cache.Put("MailResendLimit_"+u.LowerName, u.LowerName, 180); err != nil { | ||||||
|  | @ -1096,7 +1097,7 @@ func SignUpPost(ctx *context.Context, cpt *captcha.Captcha, form auth.RegisterFo | ||||||
| 		models.SendActivateAccountMail(ctx.Context, u) | 		models.SendActivateAccountMail(ctx.Context, u) | ||||||
| 		ctx.Data["IsSendRegisterMail"] = true | 		ctx.Data["IsSendRegisterMail"] = true | ||||||
| 		ctx.Data["Email"] = u.Email | 		ctx.Data["Email"] = u.Email | ||||||
| 		ctx.Data["ActiveCodeLives"] = base.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language()) | 		ctx.Data["ActiveCodeLives"] = timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language()) | ||||||
| 		ctx.HTML(200, TplActivate) | 		ctx.HTML(200, TplActivate) | ||||||
| 
 | 
 | ||||||
| 		if err := ctx.Cache.Put("MailResendLimit_"+u.LowerName, u.LowerName, 180); err != nil { | 		if err := ctx.Cache.Put("MailResendLimit_"+u.LowerName, u.LowerName, 180); err != nil { | ||||||
|  | @ -1123,7 +1124,7 @@ func Activate(ctx *context.Context) { | ||||||
| 			if ctx.Cache.IsExist("MailResendLimit_" + ctx.User.LowerName) { | 			if ctx.Cache.IsExist("MailResendLimit_" + ctx.User.LowerName) { | ||||||
| 				ctx.Data["ResendLimited"] = true | 				ctx.Data["ResendLimited"] = true | ||||||
| 			} else { | 			} else { | ||||||
| 				ctx.Data["ActiveCodeLives"] = base.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language()) | 				ctx.Data["ActiveCodeLives"] = timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language()) | ||||||
| 				models.SendActivateAccountMail(ctx.Context, ctx.User) | 				models.SendActivateAccountMail(ctx.Context, ctx.User) | ||||||
| 
 | 
 | ||||||
| 				if err := ctx.Cache.Put("MailResendLimit_"+ctx.User.LowerName, ctx.User.LowerName, 180); err != nil { | 				if err := ctx.Cache.Put("MailResendLimit_"+ctx.User.LowerName, ctx.User.LowerName, 180); err != nil { | ||||||
|  | @ -1224,7 +1225,7 @@ func ForgotPasswdPost(ctx *context.Context) { | ||||||
| 	u, err := models.GetUserByEmail(email) | 	u, err := models.GetUserByEmail(email) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if models.IsErrUserNotExist(err) { | 		if models.IsErrUserNotExist(err) { | ||||||
| 			ctx.Data["ResetPwdCodeLives"] = base.MinutesToFriendly(setting.Service.ResetPwdCodeLives, ctx.Locale.Language()) | 			ctx.Data["ResetPwdCodeLives"] = timeutil.MinutesToFriendly(setting.Service.ResetPwdCodeLives, ctx.Locale.Language()) | ||||||
| 			ctx.Data["IsResetSent"] = true | 			ctx.Data["IsResetSent"] = true | ||||||
| 			ctx.HTML(200, tplForgotPassword) | 			ctx.HTML(200, tplForgotPassword) | ||||||
| 			return | 			return | ||||||
|  | @ -1251,7 +1252,7 @@ func ForgotPasswdPost(ctx *context.Context) { | ||||||
| 		log.Error("Set cache(MailResendLimit) fail: %v", err) | 		log.Error("Set cache(MailResendLimit) fail: %v", err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	ctx.Data["ResetPwdCodeLives"] = base.MinutesToFriendly(setting.Service.ResetPwdCodeLives, ctx.Locale.Language()) | 	ctx.Data["ResetPwdCodeLives"] = timeutil.MinutesToFriendly(setting.Service.ResetPwdCodeLives, ctx.Locale.Language()) | ||||||
| 	ctx.Data["IsResetSent"] = true | 	ctx.Data["IsResetSent"] = true | ||||||
| 	ctx.HTML(200, tplForgotPassword) | 	ctx.HTML(200, tplForgotPassword) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -17,6 +17,7 @@ import ( | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/recaptcha" | 	"code.gitea.io/gitea/modules/recaptcha" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
|  | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 
 | 
 | ||||||
| 	"github.com/go-macaron/captcha" | 	"github.com/go-macaron/captcha" | ||||||
| ) | ) | ||||||
|  | @ -446,7 +447,7 @@ func RegisterOpenIDPost(ctx *context.Context, cpt *captcha.Captcha, form auth.Si | ||||||
| 		models.SendActivateAccountMail(ctx.Context, u) | 		models.SendActivateAccountMail(ctx.Context, u) | ||||||
| 		ctx.Data["IsSendRegisterMail"] = true | 		ctx.Data["IsSendRegisterMail"] = true | ||||||
| 		ctx.Data["Email"] = u.Email | 		ctx.Data["Email"] = u.Email | ||||||
| 		ctx.Data["ActiveCodeLives"] = base.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language()) | 		ctx.Data["ActiveCodeLives"] = timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language()) | ||||||
| 		ctx.HTML(200, TplActivate) | 		ctx.HTML(200, TplActivate) | ||||||
| 
 | 
 | ||||||
| 		if err := ctx.Cache.Put("MailResendLimit_"+u.LowerName, u.LowerName, 180); err != nil { | 		if err := ctx.Cache.Put("MailResendLimit_"+u.LowerName, u.LowerName, 180); err != nil { | ||||||
|  |  | ||||||
|  | @ -7,7 +7,6 @@ package user | ||||||
| import ( | import ( | ||||||
| 	"encoding/base64" | 	"encoding/base64" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"github.com/go-macaron/binding" |  | ||||||
| 	"net/url" | 	"net/url" | ||||||
| 	"strings" | 	"strings" | ||||||
| 
 | 
 | ||||||
|  | @ -17,9 +16,10 @@ import ( | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 
 | 
 | ||||||
| 	"github.com/dgrijalva/jwt-go" | 	"github.com/dgrijalva/jwt-go" | ||||||
|  | 	"github.com/go-macaron/binding" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| const ( | const ( | ||||||
|  | @ -118,7 +118,7 @@ func newAccessTokenResponse(grant *models.OAuth2Grant) (*AccessTokenResponse, *A | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	// generate access token to access the API
 | 	// generate access token to access the API
 | ||||||
| 	expirationDate := util.TimeStampNow().Add(setting.OAuth2.AccessTokenExpirationTime) | 	expirationDate := timeutil.TimeStampNow().Add(setting.OAuth2.AccessTokenExpirationTime) | ||||||
| 	accessToken := &models.OAuth2Token{ | 	accessToken := &models.OAuth2Token{ | ||||||
| 		GrantID: grant.ID, | 		GrantID: grant.ID, | ||||||
| 		Type:    models.TypeAccessToken, | 		Type:    models.TypeAccessToken, | ||||||
|  | @ -135,7 +135,7 @@ func newAccessTokenResponse(grant *models.OAuth2Grant) (*AccessTokenResponse, *A | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// generate refresh token to request an access token after it expired later
 | 	// generate refresh token to request an access token after it expired later
 | ||||||
| 	refreshExpirationDate := util.TimeStampNow().Add(setting.OAuth2.RefreshTokenExpirationTime * 60 * 60).AsTime().Unix() | 	refreshExpirationDate := timeutil.TimeStampNow().Add(setting.OAuth2.RefreshTokenExpirationTime * 60 * 60).AsTime().Unix() | ||||||
| 	refreshToken := &models.OAuth2Token{ | 	refreshToken := &models.OAuth2Token{ | ||||||
| 		GrantID: grant.ID, | 		GrantID: grant.ID, | ||||||
| 		Counter: grant.Counter, | 		Counter: grant.Counter, | ||||||
|  |  | ||||||
|  | @ -12,6 +12,7 @@ import ( | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
|  | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| const ( | const ( | ||||||
|  | @ -112,7 +113,7 @@ func EmailPost(ctx *context.Context, form auth.AddEmailForm) { | ||||||
| 		if err := ctx.Cache.Put("MailResendLimit_"+ctx.User.LowerName, ctx.User.LowerName, 180); err != nil { | 		if err := ctx.Cache.Put("MailResendLimit_"+ctx.User.LowerName, ctx.User.LowerName, 180); err != nil { | ||||||
| 			log.Error("Set cache(MailResendLimit) fail: %v", err) | 			log.Error("Set cache(MailResendLimit) fail: %v", err) | ||||||
| 		} | 		} | ||||||
| 		ctx.Flash.Info(ctx.Tr("settings.add_email_confirmation_sent", email.Email, base.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language()))) | 		ctx.Flash.Info(ctx.Tr("settings.add_email_confirmation_sent", email.Email, timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale.Language()))) | ||||||
| 	} else { | 	} else { | ||||||
| 		ctx.Flash.Success(ctx.Tr("settings.add_email_success")) | 		ctx.Flash.Success(ctx.Tr("settings.add_email_success")) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -9770,7 +9770,7 @@ | ||||||
|       "description": "TimeStamp defines a timestamp", |       "description": "TimeStamp defines a timestamp", | ||||||
|       "type": "integer", |       "type": "integer", | ||||||
|       "format": "int64", |       "format": "int64", | ||||||
|       "x-go-package": "code.gitea.io/gitea/modules/util" |       "x-go-package": "code.gitea.io/gitea/modules/timeutil" | ||||||
|     }, |     }, | ||||||
|     "TrackedTime": { |     "TrackedTime": { | ||||||
|       "description": "TrackedTime worked time for an issue / pr", |       "description": "TrackedTime worked time for an issue / pr", | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue