dkforest

A forum and chat platform (onion)
git clone https://git.dasho.dev/n0tr1v/dkforest.git
Log | Files | Refs | LICENSE

commit 4f55f4701ee6dca2d18d4491fb24d3b291ab3571
parent 8b8c7049996364ca6873c9ae932fda5b780c1528
Author: n0tr1v <n0tr1v@protonmail.com>
Date:   Sun,  4 Dec 2022 18:32:01 -0500

allows to quick link to archive message with mm-dd HH:MM:SS format

Diffstat:
Mpkg/database/tableChatMessages.go | 4++--
Mpkg/utils/utils.go | 42+++++++++++++++++++++++++++++++++++++++---
Mpkg/web/handlers/api/v1/topBarHandler.go | 30+++++++++++++++++++-----------
3 files changed, 60 insertions(+), 16 deletions(-)

diff --git a/pkg/database/tableChatMessages.go b/pkg/database/tableChatMessages.go @@ -256,8 +256,8 @@ func GetRoomChatMessageByDate(roomID int64, userID UserID, dt time.Time) (out Ch func GetRoomChatMessagesByDate(roomID int64, dt time.Time) (out []ChatMessage, err error) { err = DB. - Select("*, strftime('%H:%M:%S', created_at) as created_at1"). - Where("room_id = ? AND created_at1 = ?", roomID, dt.Format("15:04:05")). + Select("*, strftime('%m-%d %H:%M:%S', created_at) as created_at1"). + Where("room_id = ? AND created_at1 = ?", roomID, dt.Format("01-02 15:04:05")). Preload("User"). Preload("ToUser"). Preload("Room"). diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go @@ -777,6 +777,7 @@ func WordCount(str string) (int, map[string]int) { } var hourMinSecRgx = regexp.MustCompile(`^\d{2}:\d{2}:\d{2}$`) +var monthDayHourMinSecRgx = regexp.MustCompile(`^\d{2}-\d{2} \d{2}:\d{2}:\d{2}$`) // ParseNextDatetimeAt given a string in this format 00:00:00 returns the next Time object at that time. func ParseNextDatetimeAt(hourMinSec string, clock clockwork.Clock) (time.Time, error) { @@ -814,18 +815,30 @@ func GetNextDatetimeAt(hour, min, sec int64, clock clockwork.Clock) (time.Time, return parsedDate, nil } -// ParsePrevDatetimeAt given a string in this format 00:00:00 returns the previous Time object at that time. +// ParsePrevDatetimeAt given a string in this format HH:MM:SS returns the previous Time object at that time. func ParsePrevDatetimeAt(hourMinSec string, clock clockwork.Clock) (time.Time, error) { if !hourMinSecRgx.MatchString(hourMinSec) { - return time.Time{}, errors.New("invalid format (should be 00:00:00)") + return time.Time{}, errors.New("invalid format (should be HH:MM:SS)") } var hour, min, sec int64 if n, err := fmt.Sscanf(hourMinSec, "%d:%d:%d", &hour, &min, &sec); err != nil || n != 3 { - return time.Time{}, errors.New("invalid format (should be 00:00:00)") + return time.Time{}, errors.New("invalid format (should be HH:MM:SS)") } return GetPrevDatetimeAt(hour, min, sec, clock) } +// ParsePrevDatetimeAt2 given a string in this format "mm-dd HH:MM:SS" returns the previous Time object at that time. +func ParsePrevDatetimeAt2(monthDayHourMinSec string, clock clockwork.Clock) (time.Time, error) { + if !monthDayHourMinSecRgx.MatchString(monthDayHourMinSec) { + return time.Time{}, errors.New("invalid format (should be mm-dd HH:MM:SS)") + } + var month, day, hour, min, sec int64 + if n, err := fmt.Sscanf(monthDayHourMinSec, "%d-%d %d:%d:%d", &month, &day, &hour, &min, &sec); err != nil || n != 5 { + return time.Time{}, errors.New("invalid format (should be mm-dd HH:MM:SS)") + } + return GetPrevDatetimeAt2(month, day, hour, min, sec, clock) +} + // GetPrevDatetimeAt given a hour, minute, second, returns the previous Time object at that time. func GetPrevDatetimeAt(hour, min, sec int64, clock clockwork.Clock) (time.Time, error) { if hour < 0 || hour > 23 { @@ -850,6 +863,29 @@ func GetPrevDatetimeAt(hour, min, sec int64, clock clockwork.Clock) (time.Time, return parsedDate, nil } +// GetPrevDatetimeAt2 given a month, day, hour, minute, second, returns the previous Time object at that time. +func GetPrevDatetimeAt2(month, day, hour, min, sec int64, clock clockwork.Clock) (time.Time, error) { + if month < 1 || month > 12 { + return time.Time{}, errors.New("month must be between [1, 12]") + } + if day < 1 || day > 31 { + return time.Time{}, errors.New("day must be between [1, 31]") + } + if hour < 0 || hour > 23 { + return time.Time{}, errors.New("hour must be between [0, 23]") + } + if min < 0 || min > 59 { + return time.Time{}, errors.New("min must be between [0, 59]") + } + if sec < 0 || sec > 59 { + return time.Time{}, errors.New("sec must be between [0, 59]") + } + monthDayHourMinSec := fmt.Sprintf("%02d-%02d %02d:%02d:%02d", month, day, hour, min, sec) + timeNow := clock.Now() + parsedDate, _ := time.ParseInLocation("2006 01-02 15:04:05", timeNow.Format("2006")+" "+monthDayHourMinSec, timeNow.Location()) + return parsedDate, nil +} + // ReencodePng to remove metadata func ReencodePng(in []byte) (out []byte, err error) { var buf bytes.Buffer diff --git a/pkg/web/handlers/api/v1/topBarHandler.go b/pkg/web/handlers/api/v1/topBarHandler.go @@ -587,22 +587,30 @@ func convertArchiveLinks(html string, roomID int64, authUserID database.UserID) start, rest = html[:endOfQuoteIdx], html[endOfQuoteIdx:] } - archiveRgx := regexp.MustCompile(`\d{2}:\d{2}:\d{2}`) + archiveRgx := regexp.MustCompile(`(\d{2}-\d{2} )?\d{2}:\d{2}:\d{2}`) if archiveRgx.MatchString(rest) { rest = archiveRgx.ReplaceAllStringFunc(rest, func(s string) string { - if dt, err := utils.ParsePrevDatetimeAt(s, clockwork.NewRealClock()); err == nil { - if msgs, err := database.GetRoomChatMessagesByDate(roomID, dt.UTC()); err == nil && len(msgs) > 0 { - msg := msgs[0] - if len(msgs) > 1 { - for _, msgTmp := range msgs { - if msgTmp.User.ID == authUserID || (msgTmp.ToUserID != nil && *msgTmp.ToUserID == authUserID) { - msg = msgTmp - break - } + var dt time.Time + var err error + if len(s) == 8 { // HH:MM:SS + dt, err = utils.ParsePrevDatetimeAt(s, clockwork.NewRealClock()) + } else if len(s) == 14 { // mm-dd HH:MM:SS + dt, err = utils.ParsePrevDatetimeAt2(s, clockwork.NewRealClock()) + } + if err != nil { + return s + } + if msgs, err := database.GetRoomChatMessagesByDate(roomID, dt.UTC()); err == nil && len(msgs) > 0 { + msg := msgs[0] + if len(msgs) > 1 { + for _, msgTmp := range msgs { + if msgTmp.User.ID == authUserID || (msgTmp.ToUserID != nil && *msgTmp.ToUserID == authUserID) { + msg = msgTmp + break } } - return fmt.Sprintf(`<a href="/chat/%s/archive#%s" target="_blank" rel="noopener noreferrer">%s</a>`, msg.Room.Name, msg.UUID, s) } + return fmt.Sprintf(`<a href="/chat/%s/archive#%s" target="_blank" rel="noopener noreferrer">%s</a>`, msg.Room.Name, msg.UUID, s) } return s })