Fixed timezone things with postgresql and made "Forever" work.

This commit is contained in:
Stanislav Nikitin 2018-12-01 03:49:04 +05:00
parent aa5e11329f
commit c565ec8f21
4 changed files with 56 additions and 24 deletions

View File

@ -46,7 +46,7 @@ func InitialUp(tx *sql.Tx) error {
COMMENT ON COLUMN pastes.data IS 'Paste data';
COMMENT ON COLUMN pastes.created_at IS 'Paste creation timestamp';
COMMENT ON COLUMN pastes.keep_for IS 'Keep for integer. 0 - forever.';
COMMENT ON COLUMN pastes.keep_for_unit_type IS 'Keep for unit type. 1 - minutes, 2 - hours, 3 - days, 4 - months.';
COMMENT ON COLUMN pastes.keep_for_unit_type IS 'Keep for unit type. 0 - forever, 1 - minutes, 2 - hours, 3 - days, 4 - months.';
`)
if err != nil {
return err

View File

@ -28,6 +28,7 @@ import (
// stdlib
"database/sql"
"fmt"
"time"
// local
"gitlab.com/pztrn/fastpastebin/database/dialects/postgresql/migrations"
@ -66,6 +67,13 @@ func (db *Database) GetPaste(pasteID int) (*pastesmodel.Paste, error) {
return nil, err
}
// We're aware of timezone in PostgreSQL, so SELECT will return
// timestamps in server's local timezone. We should convert them.
loc, _ := time.LoadLocation("UTC")
utcCreatedAt := p.CreatedAt.In(loc)
p.CreatedAt = &utcCreatedAt
return p, nil
}
@ -85,9 +93,15 @@ func (db *Database) GetPagedPastes(page int) ([]pastesmodel.Paste, error) {
return nil, err
}
for i := range pastesRaw {
if !pastesRaw[i].IsExpired() {
pastes = append(pastes, pastesRaw[i])
// We're aware of timezone in PostgreSQL, so SELECT will return
// timestamps in server's local timezone. We should convert them.
loc, _ := time.LoadLocation("UTC")
for _, paste := range pastesRaw {
if !paste.IsExpired() {
utcCreatedAt := paste.CreatedAt.In(loc)
paste.CreatedAt = &utcCreatedAt
pastes = append(pastes, paste)
}
}
@ -104,9 +118,9 @@ func (db *Database) GetPastesPages() int {
}
// Check if pastes isn't expired.
for i := range pastesRaw {
if !pastesRaw[i].IsExpired() {
pastes = append(pastes, pastesRaw[i])
for _, paste := range pastesRaw {
if !paste.IsExpired() {
pastes = append(pastes, paste)
}
}

View File

@ -118,9 +118,14 @@ func pasteGET(ec echo.Context) error {
pasteData["pasteTitle"] = paste.Title
pasteData["pasteID"] = strconv.Itoa(paste.ID)
pasteData["pasteDate"] = paste.CreatedAt.Format("2006-01-02 @ 15:04:05") + " UTC"
pasteData["pasteExpiration"] = paste.GetExpirationTime().Format("2006-01-02 @ 15:04:05") + " UTC"
pasteData["pasteLanguage"] = paste.Language
pasteExpirationString := "Never"
if paste.KeepFor != 0 && paste.KeepForUnitType != 0 {
pasteExpirationString = paste.GetExpirationTime().Format("2006-01-02 @ 15:04:05") + " UTC"
}
pasteData["pasteExpiration"] = pasteExpirationString
if paste.Private {
pasteData["pasteType"] = "<span class='has-text-danger'>Private</span>"
pasteData["pasteTs"] = strconv.FormatInt(paste.CreatedAt.Unix(), 10) + "/"
@ -264,7 +269,7 @@ func pastePOST(ec echo.Context) error {
return ec.HTML(http.StatusBadRequest, errtpl)
}
if !strings.ContainsAny(params["paste-keep-for"][0], "Mmhd") {
if !strings.ContainsAny(params["paste-keep-for"][0], "Mmhd") && params["paste-keep-for"][0] != "forever" {
c.Logger.Debug().Msgf("'Keep paste for' field have invalid value: %s", params["paste-keep-for"][0])
errtpl := templater.GetErrorTemplate(ec, "Invalid 'Paste should be available for' parameter passed. Please do not try to hack us ;).")
return ec.HTML(http.StatusBadRequest, errtpl)
@ -288,21 +293,30 @@ func pastePOST(ec echo.Context) error {
paste.CreatedAt = &createdAt
// Parse "keep for" field.
// Defaulting to "forever".
keepFor := 0
keepForUnit := 0
if params["paste-keep-for"][0] != "forever" {
keepForUnitRegex := regexp.MustCompile("[Mmhd]")
// Get integers and strings separately.
keepForUnitRegex := regexp.MustCompile("[Mmhd]")
keepForRaw := regexInts.FindAllString(params["paste-keep-for"][0], 1)[0]
var err error
keepFor, err = strconv.Atoi(keepForRaw)
if err != nil {
if params["paste-keep-for"][0] == "forever" {
c.Logger.Debug().Msg("Keeping paste forever!")
keepFor = 0
} else {
c.Logger.Debug().Err(err).Msg("Failed to parse 'Keep for' integer")
errtpl := templater.GetErrorTemplate(ec, "Invalid 'Paste should be available for' parameter passed. Please do not try to hack us ;).")
return ec.HTML(http.StatusBadRequest, errtpl)
}
}
keepForRaw := regexInts.FindAllString(params["paste-keep-for"][0], 1)[0]
keepFor, err1 := strconv.Atoi(keepForRaw)
if err1 != nil {
c.Logger.Debug().Msgf("Failed to parse 'Keep for' integer: %s", err1.Error())
errtpl := templater.GetErrorTemplate(ec, "Invalid 'Paste should be available for' parameter passed. Please do not try to hack us ;).")
return ec.HTML(http.StatusBadRequest, errtpl)
keepForUnitRaw := keepForUnitRegex.FindAllString(params["paste-keep-for"][0], 1)[0]
keepForUnit = pastesmodel.PASTE_KEEPS_CORELLATION[keepForUnitRaw]
}
paste.KeepFor = keepFor
keepForUnitRaw := keepForUnitRegex.FindAllString(params["paste-keep-for"][0], 1)[0]
keepForUnit := pastesmodel.PASTE_KEEPS_CORELLATION[keepForUnitRaw]
paste.KeepForUnitType = keepForUnit
// Try to autodetect if it was selected.

View File

@ -36,6 +36,7 @@ import (
)
const (
PASTE_KEEP_FOREVER = 0
PASTE_KEEP_FOR_MINUTES = 1
PASTE_KEEP_FOR_HOURS = 2
PASTE_KEEP_FOR_DAYS = 3
@ -46,10 +47,11 @@ const (
var (
PASTE_KEEPS_CORELLATION = map[string]int{
"M": PASTE_KEEP_FOR_MINUTES,
"h": PASTE_KEEP_FOR_HOURS,
"d": PASTE_KEEP_FOR_DAYS,
"m": PASTE_KEEP_FOR_MONTHS,
"M": PASTE_KEEP_FOR_MINUTES,
"h": PASTE_KEEP_FOR_HOURS,
"d": PASTE_KEEP_FOR_DAYS,
"m": PASTE_KEEP_FOR_MONTHS,
"forever": PASTE_KEEP_FOREVER,
}
)
@ -99,6 +101,8 @@ func (p *Paste) GenerateCryptedCookieValue() string {
func (p *Paste) GetExpirationTime() time.Time {
var expirationTime time.Time
switch p.KeepForUnitType {
case PASTE_KEEP_FOREVER:
expirationTime = time.Now().UTC().Add(time.Hour * 1)
case PASTE_KEEP_FOR_MINUTES:
expirationTime = p.CreatedAt.Add(time.Minute * time.Duration(p.KeepFor))
case PASTE_KEEP_FOR_HOURS: