opengist/internal/web/util.go

249 lines
6.1 KiB
Go
Raw Permalink Normal View History

2023-03-14 15:22:52 +00:00
package web
import (
"context"
"errors"
"github.com/gorilla/sessions"
"github.com/labstack/echo/v4"
"github.com/rs/zerolog/log"
"github.com/thomiceli/opengist/internal/config"
2023-09-02 22:30:57 +00:00
"github.com/thomiceli/opengist/internal/db"
2023-09-22 15:26:09 +00:00
"github.com/thomiceli/opengist/internal/i18n"
2024-09-03 15:15:08 +00:00
"golang.org/x/text/cases"
"golang.org/x/text/language"
2023-03-14 15:22:52 +00:00
"html/template"
"net/http"
"strconv"
"strings"
)
2023-04-26 21:13:11 +00:00
type dataTypeKey string
const dataKey dataTypeKey = "data"
2023-03-14 15:22:52 +00:00
func setData(ctx echo.Context, key string, value any) {
2023-04-26 21:13:11 +00:00
data := ctx.Request().Context().Value(dataKey).(echo.Map)
2023-03-14 15:22:52 +00:00
data[key] = value
2023-04-26 21:13:11 +00:00
ctxValue := context.WithValue(ctx.Request().Context(), dataKey, data)
2023-03-14 15:22:52 +00:00
ctx.SetRequest(ctx.Request().WithContext(ctxValue))
}
func getData(ctx echo.Context, key string) any {
2023-04-26 21:13:11 +00:00
data := ctx.Request().Context().Value(dataKey).(echo.Map)
2023-03-14 15:22:52 +00:00
return data[key]
}
func dataMap(ctx echo.Context) echo.Map {
return ctx.Request().Context().Value(dataKey).(echo.Map)
}
2023-03-14 15:22:52 +00:00
func html(ctx echo.Context, template string) error {
return htmlWithCode(ctx, 200, template)
}
func htmlWithCode(ctx echo.Context, code int, template string) error {
setErrorFlashes(ctx)
2023-04-26 21:13:11 +00:00
return ctx.Render(code, template, ctx.Request().Context().Value(dataKey))
2023-03-14 15:22:52 +00:00
}
2024-10-31 13:41:42 +00:00
func json(ctx echo.Context, data any) error {
return jsonWithCode(ctx, 200, data)
}
func jsonWithCode(ctx echo.Context, code int, data any) error {
2024-10-07 21:56:32 +00:00
return ctx.JSON(code, data)
}
2023-03-14 15:22:52 +00:00
func redirect(ctx echo.Context, location string) error {
return ctx.Redirect(302, config.C.ExternalUrl+location)
2023-03-14 15:22:52 +00:00
}
func plainText(ctx echo.Context, code int, message string) error {
return ctx.String(code, message)
}
func notFound(message string) error {
return errorRes(404, message, nil)
}
func errorRes(code int, message string, err error) error {
if code >= 500 {
var skipLogger = log.With().CallerWithSkipFrameCount(3).Logger()
skipLogger.Error().Err(err).Msg(message)
}
2024-10-31 13:41:42 +00:00
return &echo.HTTPError{Code: code, Message: message, Internal: err}
2024-10-07 21:56:32 +00:00
}
func jsonErrorRes(code int, message string, err error) error {
if code >= 500 {
var skipLogger = log.With().CallerWithSkipFrameCount(3).Logger()
skipLogger.Error().Err(err).Msg(message)
}
2024-10-31 13:41:42 +00:00
return &echo.HTTPError{Code: code, Message: message, Internal: err}
2023-03-14 15:22:52 +00:00
}
2023-09-02 22:30:57 +00:00
func getUserLogged(ctx echo.Context) *db.User {
2023-03-14 15:22:52 +00:00
user := getData(ctx, "userLogged")
if user != nil {
2023-09-02 22:30:57 +00:00
return user.(*db.User)
2023-03-14 15:22:52 +00:00
}
return nil
}
func setErrorFlashes(ctx echo.Context) {
2024-04-02 23:48:31 +00:00
sess, _ := flashStore.Get(ctx.Request(), "flash")
2023-03-14 15:22:52 +00:00
setData(ctx, "flashErrors", sess.Flashes("error"))
setData(ctx, "flashSuccess", sess.Flashes("success"))
2024-10-24 21:23:00 +00:00
setData(ctx, "flashWarnings", sess.Flashes("warning"))
2023-03-14 15:22:52 +00:00
_ = sess.Save(ctx.Request(), ctx.Response())
}
func addFlash(ctx echo.Context, flashMessage string, flashType string) {
2024-04-02 23:48:31 +00:00
sess, _ := flashStore.Get(ctx.Request(), "flash")
2023-03-14 15:22:52 +00:00
sess.AddFlash(flashMessage, flashType)
_ = sess.Save(ctx.Request(), ctx.Response())
}
func getSession(ctx echo.Context) *sessions.Session {
2024-04-02 23:48:31 +00:00
sess, _ := userStore.Get(ctx.Request(), "session")
2023-03-14 15:22:52 +00:00
return sess
}
func saveSession(sess *sessions.Session, ctx echo.Context) {
_ = sess.Save(ctx.Request(), ctx.Response())
}
func deleteSession(ctx echo.Context) {
sess := getSession(ctx)
sess.Options.MaxAge = -1
saveSession(sess, ctx)
}
func setCsrfHtmlForm(ctx echo.Context) {
2024-10-07 21:56:32 +00:00
var csrf string
2023-03-14 15:22:52 +00:00
if csrfToken, ok := ctx.Get("csrf").(string); ok {
2024-10-07 21:56:32 +00:00
csrf = csrfToken
2023-03-14 15:22:52 +00:00
}
2024-10-07 21:56:32 +00:00
setData(ctx, "csrfHtml", template.HTML(`<input type="hidden" name="_csrf" value="`+csrf+`">`))
2023-03-14 15:22:52 +00:00
}
func deleteCsrfCookie(ctx echo.Context) {
ctx.SetCookie(&http.Cookie{Name: "_csrf", Path: "/", MaxAge: -1})
}
2023-04-28 18:31:10 +00:00
func loadSettings(ctx echo.Context) error {
2023-09-02 22:30:57 +00:00
settings, err := db.GetSettings()
2023-04-28 18:31:10 +00:00
if err != nil {
return err
}
for key, value := range settings {
s := strings.ReplaceAll(key, "-", " ")
2024-09-03 15:15:08 +00:00
s = cases.Title(language.English).String(s)
2023-04-28 18:31:10 +00:00
setData(ctx, strings.ReplaceAll(s, " ", ""), value == "1")
}
return nil
}
2023-03-14 15:22:52 +00:00
func getPage(ctx echo.Context) int {
page := ctx.QueryParam("page")
if page == "" {
page = "1"
}
pageInt, err := strconv.Atoi(page)
if err != nil {
pageInt = 1
}
setData(ctx, "currPage", pageInt)
return pageInt
}
2023-03-15 00:26:56 +00:00
func paginate[T any](ctx echo.Context, data []*T, pageInt int, perPage int, templateDataName string, urlPage string, labels int, urlParams ...string) error {
2023-03-14 15:22:52 +00:00
lenData := len(data)
if lenData == 0 && pageInt != 1 {
return errors.New("page not found")
}
if lenData > perPage {
if lenData > 1 {
data = data[:lenData-1]
}
setData(ctx, "nextPage", pageInt+1)
}
if pageInt > 1 {
setData(ctx, "prevPage", pageInt-1)
}
if len(urlParams) > 0 {
setData(ctx, "urlParams", template.URL(urlParams[0]))
}
2023-03-15 00:26:56 +00:00
switch labels {
case 1:
2024-05-04 22:24:25 +00:00
setData(ctx, "prevLabel", trH(ctx, "pagination.previous"))
setData(ctx, "nextLabel", trH(ctx, "pagination.next"))
2023-03-15 00:26:56 +00:00
case 2:
2024-05-04 22:24:25 +00:00
setData(ctx, "prevLabel", trH(ctx, "pagination.newer"))
setData(ctx, "nextLabel", trH(ctx, "pagination.older"))
2023-03-15 00:26:56 +00:00
}
2023-03-14 15:22:52 +00:00
setData(ctx, "urlPage", urlPage)
setData(ctx, templateDataName, data)
return nil
}
2024-05-04 22:24:25 +00:00
func trH(ctx echo.Context, key string, args ...any) template.HTML {
2023-09-22 15:26:09 +00:00
l := getData(ctx, "locale").(*i18n.Locale)
2024-05-04 22:24:25 +00:00
return l.Tr(key, args...)
}
func tr(ctx echo.Context, key string, args ...any) string {
l := getData(ctx, "locale").(*i18n.Locale)
return l.String(key, args...)
2023-09-22 15:26:09 +00:00
}
2024-01-04 02:38:15 +00:00
func parseSearchQueryStr(query string) (string, map[string]string) {
words := strings.Fields(query)
metadata := make(map[string]string)
var contentBuilder strings.Builder
for _, word := range words {
if strings.Contains(word, ":") {
keyValue := strings.SplitN(word, ":", 2)
if len(keyValue) == 2 {
key := keyValue[0]
value := keyValue[1]
metadata[key] = value
}
} else {
contentBuilder.WriteString(word + " ")
}
}
content := strings.TrimSpace(contentBuilder.String())
return content, metadata
}
func addMetadataToSearchQuery(input, key, value string) string {
content, metadata := parseSearchQueryStr(input)
metadata[key] = value
var resultBuilder strings.Builder
resultBuilder.WriteString(content)
for k, v := range metadata {
resultBuilder.WriteString(" ")
resultBuilder.WriteString(k)
resultBuilder.WriteString(":")
resultBuilder.WriteString(v)
}
return strings.TrimSpace(resultBuilder.String())
}