2018-10-25 21:51:47 +08:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"net/http"
|
|
|
|
"strconv"
|
2021-12-10 00:04:38 +08:00
|
|
|
"strings"
|
2018-10-25 21:51:47 +08:00
|
|
|
|
|
|
|
"github.com/knadh/listmonk/models"
|
2021-12-09 23:21:07 +08:00
|
|
|
"github.com/labstack/echo/v4"
|
2018-10-25 21:51:47 +08:00
|
|
|
)
|
|
|
|
|
2021-09-18 22:45:24 +08:00
|
|
|
// handleGetLists retrieves lists with additional metadata like subscriber counts. This may be slow.
|
2018-10-25 21:51:47 +08:00
|
|
|
func handleGetLists(c echo.Context) error {
|
|
|
|
var (
|
|
|
|
app = c.Get("app").(*App)
|
2022-11-09 02:05:31 +08:00
|
|
|
pg = app.paginator.NewFromURL(c.Request().URL.Query())
|
2018-10-25 21:51:47 +08:00
|
|
|
|
2021-12-10 00:04:38 +08:00
|
|
|
query = strings.TrimSpace(c.FormValue("query"))
|
2023-12-23 17:15:55 +08:00
|
|
|
tags = c.QueryParams()["tag"]
|
2021-09-18 22:45:24 +08:00
|
|
|
orderBy = c.FormValue("order_by")
|
2023-12-23 17:15:55 +08:00
|
|
|
typ = c.FormValue("type")
|
|
|
|
optin = c.FormValue("optin")
|
2021-09-18 22:45:24 +08:00
|
|
|
order = c.FormValue("order")
|
|
|
|
minimal, _ = strconv.ParseBool(c.FormValue("minimal"))
|
|
|
|
listID, _ = strconv.Atoi(c.Param("id"))
|
2022-11-09 02:05:31 +08:00
|
|
|
|
|
|
|
out models.PageResults
|
2018-10-25 21:51:47 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
// Fetch one list.
|
2021-12-10 00:04:38 +08:00
|
|
|
single := false
|
2018-10-25 21:51:47 +08:00
|
|
|
if listID > 0 {
|
|
|
|
single = true
|
|
|
|
}
|
|
|
|
|
2022-11-23 01:41:05 +08:00
|
|
|
if single {
|
|
|
|
out, err := app.core.GetList(listID, "")
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return c.JSON(http.StatusOK, okResp{out})
|
|
|
|
}
|
|
|
|
|
2021-12-10 00:04:38 +08:00
|
|
|
// Minimal query simply returns the list of all lists without JOIN subscriber counts. This is fast.
|
2021-09-18 22:45:24 +08:00
|
|
|
if !single && minimal {
|
2022-04-03 23:24:40 +08:00
|
|
|
res, err := app.core.GetLists("")
|
|
|
|
if err != nil {
|
|
|
|
return err
|
2021-09-18 22:45:24 +08:00
|
|
|
}
|
2022-04-03 23:24:40 +08:00
|
|
|
if len(res) == 0 {
|
2021-09-18 22:45:24 +08:00
|
|
|
return c.JSON(http.StatusOK, okResp{[]struct{}{}})
|
|
|
|
}
|
|
|
|
|
|
|
|
// Meta.
|
2022-04-03 23:24:40 +08:00
|
|
|
out.Results = res
|
|
|
|
out.Total = len(res)
|
2021-09-18 22:45:24 +08:00
|
|
|
out.Page = 1
|
|
|
|
out.PerPage = out.Total
|
2022-04-03 23:24:40 +08:00
|
|
|
|
2021-09-18 22:45:24 +08:00
|
|
|
return c.JSON(http.StatusOK, okResp{out})
|
|
|
|
}
|
|
|
|
|
2022-04-03 23:24:40 +08:00
|
|
|
// Full list query.
|
2023-12-23 17:15:55 +08:00
|
|
|
res, total, err := app.core.QueryLists(query, typ, optin, tags, orderBy, order, pg.Offset, pg.Limit)
|
2022-04-03 23:24:40 +08:00
|
|
|
if err != nil {
|
|
|
|
return err
|
2019-10-25 13:41:47 +08:00
|
|
|
}
|
2022-04-03 23:24:40 +08:00
|
|
|
|
|
|
|
if single && len(res) == 0 {
|
2020-12-19 18:55:52 +08:00
|
|
|
return echo.NewHTTPError(http.StatusBadRequest,
|
2021-01-23 21:24:33 +08:00
|
|
|
app.i18n.Ts("globals.messages.notFound", "name", "{globals.terms.list}"))
|
2019-10-25 13:41:47 +08:00
|
|
|
}
|
2018-10-25 21:51:47 +08:00
|
|
|
|
|
|
|
if single {
|
2022-04-03 23:24:40 +08:00
|
|
|
return c.JSON(http.StatusOK, okResp{res[0]})
|
2018-10-25 21:51:47 +08:00
|
|
|
}
|
|
|
|
|
2022-05-01 17:42:31 +08:00
|
|
|
out.Query = query
|
2022-04-03 23:24:40 +08:00
|
|
|
out.Results = res
|
2022-05-01 17:42:31 +08:00
|
|
|
out.Total = total
|
2019-05-14 19:11:05 +08:00
|
|
|
out.Page = pg.Page
|
|
|
|
out.PerPage = pg.PerPage
|
2021-09-18 21:44:58 +08:00
|
|
|
|
2018-10-25 21:51:47 +08:00
|
|
|
return c.JSON(http.StatusOK, okResp{out})
|
|
|
|
}
|
|
|
|
|
|
|
|
// handleCreateList handles list creation.
|
|
|
|
func handleCreateList(c echo.Context) error {
|
|
|
|
var (
|
|
|
|
app = c.Get("app").(*App)
|
2022-04-03 23:24:40 +08:00
|
|
|
l = models.List{}
|
2018-10-25 21:51:47 +08:00
|
|
|
)
|
|
|
|
|
2022-04-03 23:24:40 +08:00
|
|
|
if err := c.Bind(&l); err != nil {
|
2018-10-25 21:51:47 +08:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Validate.
|
2022-04-03 23:24:40 +08:00
|
|
|
if !strHasLen(l.Name, 1, stdInputMaxLen) {
|
2020-12-19 18:55:52 +08:00
|
|
|
return echo.NewHTTPError(http.StatusBadRequest, app.i18n.T("lists.invalidName"))
|
2018-10-25 21:51:47 +08:00
|
|
|
}
|
|
|
|
|
2022-04-03 23:24:40 +08:00
|
|
|
out, err := app.core.CreateList(l)
|
2020-03-07 23:07:48 +08:00
|
|
|
if err != nil {
|
2022-04-03 23:24:40 +08:00
|
|
|
return err
|
2018-10-25 21:51:47 +08:00
|
|
|
}
|
|
|
|
|
2022-04-03 23:24:40 +08:00
|
|
|
return c.JSON(http.StatusOK, okResp{out})
|
2018-10-25 21:51:47 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// handleUpdateList handles list modification.
|
|
|
|
func handleUpdateList(c echo.Context) error {
|
|
|
|
var (
|
|
|
|
app = c.Get("app").(*App)
|
|
|
|
id, _ = strconv.Atoi(c.Param("id"))
|
|
|
|
)
|
|
|
|
|
|
|
|
if id < 1 {
|
2020-12-19 18:55:52 +08:00
|
|
|
return echo.NewHTTPError(http.StatusBadRequest, app.i18n.T("globals.messages.invalidID"))
|
2018-10-25 21:51:47 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Incoming params.
|
2022-04-03 23:24:40 +08:00
|
|
|
var l models.List
|
|
|
|
if err := c.Bind(&l); err != nil {
|
2018-10-25 21:51:47 +08:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2022-04-03 23:24:40 +08:00
|
|
|
// Validate.
|
|
|
|
if !strHasLen(l.Name, 1, stdInputMaxLen) {
|
|
|
|
return echo.NewHTTPError(http.StatusBadRequest, app.i18n.T("lists.invalidName"))
|
2018-10-25 21:51:47 +08:00
|
|
|
}
|
|
|
|
|
2022-04-03 23:24:40 +08:00
|
|
|
out, err := app.core.UpdateList(id, l)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
2018-10-25 21:51:47 +08:00
|
|
|
}
|
|
|
|
|
2022-04-03 23:24:40 +08:00
|
|
|
return c.JSON(http.StatusOK, okResp{out})
|
2018-10-25 21:51:47 +08:00
|
|
|
}
|
|
|
|
|
2021-05-25 01:11:48 +08:00
|
|
|
// handleDeleteLists handles list deletion, either a single one (ID in the URI), or a list.
|
2018-10-25 21:51:47 +08:00
|
|
|
func handleDeleteLists(c echo.Context) error {
|
|
|
|
var (
|
|
|
|
app = c.Get("app").(*App)
|
|
|
|
id, _ = strconv.ParseInt(c.Param("id"), 10, 64)
|
2022-04-03 23:24:40 +08:00
|
|
|
ids []int
|
2018-10-25 21:51:47 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
if id < 1 && len(ids) == 0 {
|
2020-12-19 18:55:52 +08:00
|
|
|
return echo.NewHTTPError(http.StatusBadRequest, app.i18n.T("globals.messages.invalidID"))
|
2018-10-25 21:51:47 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if id > 0 {
|
2022-04-03 23:24:40 +08:00
|
|
|
ids = append(ids, int(id))
|
2018-10-25 21:51:47 +08:00
|
|
|
}
|
|
|
|
|
2022-04-03 23:24:40 +08:00
|
|
|
if err := app.core.DeleteLists(ids); err != nil {
|
|
|
|
return err
|
2018-10-25 21:51:47 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return c.JSON(http.StatusOK, okResp{true})
|
|
|
|
}
|