forked from knadh/listmonk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
lists.go
172 lines (142 loc) · 5.13 KB
/
lists.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
package core
import (
"net/http"
"github.com/gofrs/uuid"
"github.com/knadh/listmonk/models"
"github.com/labstack/echo/v4"
"github.com/lib/pq"
)
// GetLists gets all lists optionally filtered by type.
func (c *Core) GetLists(typ string) ([]models.List, error) {
out := []models.List{}
if err := c.q.GetLists.Select(&out, typ, "id"); err != nil {
c.log.Printf("error fetching lists: %v", err)
return nil, echo.NewHTTPError(http.StatusInternalServerError,
c.i18n.Ts("globals.messages.errorFetching", "name", "{globals.terms.lists}", "error", pqErrMsg(err)))
}
// Replace null tags.
for i, l := range out {
if l.Tags == nil {
out[i].Tags = []string{}
}
// Total counts.
for _, c := range l.SubscriberCounts {
out[i].SubscriberCount += c
}
}
return out, nil
}
// QueryLists gets multiple lists based on multiple query params. Along with the paginated and sliced
// results, the total number of lists in the DB is returned.
func (c *Core) QueryLists(searchStr, orderBy, order string, offset, limit int) ([]models.List, int, error) {
out := []models.List{}
queryStr, stmt := makeSearchQuery(searchStr, orderBy, order, c.q.QueryLists)
if err := c.db.Select(&out, stmt, 0, "", queryStr, offset, limit); err != nil {
c.log.Printf("error fetching lists: %v", err)
return nil, 0, echo.NewHTTPError(http.StatusInternalServerError,
c.i18n.Ts("globals.messages.errorFetching", "name", "{globals.terms.lists}", "error", pqErrMsg(err)))
}
total := 0
if len(out) > 0 {
total = out[0].Total
// Replace null tags.
for i, l := range out {
if l.Tags == nil {
out[i].Tags = []string{}
}
// Total counts.
for _, c := range l.SubscriberCounts {
out[i].SubscriberCount += c
}
}
}
return out, total, nil
}
// GetList gets a list by its ID or UUID.
func (c *Core) GetList(id int, uuid string) (models.List, error) {
var uu interface{}
if uuid != "" {
uu = uuid
}
var res []models.List
queryStr, stmt := makeSearchQuery("", "", "", c.q.QueryLists)
if err := c.db.Select(&res, stmt, id, uu, queryStr, 0, 1); err != nil {
c.log.Printf("error fetching lists: %v", err)
return models.List{}, echo.NewHTTPError(http.StatusInternalServerError,
c.i18n.Ts("globals.messages.errorFetching", "name", "{globals.terms.lists}", "error", pqErrMsg(err)))
}
if len(res) == 0 {
return models.List{}, echo.NewHTTPError(http.StatusBadRequest,
c.i18n.Ts("globals.messages.notFound", "name", "{globals.terms.list}"))
}
out := res[0]
if out.Tags == nil {
out.Tags = []string{}
}
// Total counts.
for _, c := range out.SubscriberCounts {
out.SubscriberCount += c
}
return out, nil
}
// GetListsByOptin returns lists by optin type.
func (c *Core) GetListsByOptin(ids []int, optinType string) ([]models.List, error) {
out := []models.List{}
if err := c.q.GetListsByOptin.Select(&out, optinType, pq.Array(ids), nil); err != nil {
c.log.Printf("error fetching lists for opt-in: %s", pqErrMsg(err))
return nil, echo.NewHTTPError(http.StatusInternalServerError,
c.i18n.Ts("globals.messages.errorFetching", "name", "{globals.terms.list}", "error", pqErrMsg(err)))
}
return out, nil
}
// CreateList creates a new list.
func (c *Core) CreateList(l models.List) (models.List, error) {
uu, err := uuid.NewV4()
if err != nil {
c.log.Printf("error generating UUID: %v", err)
return models.List{}, echo.NewHTTPError(http.StatusInternalServerError,
c.i18n.Ts("globals.messages.errorUUID", "error", err.Error()))
}
if l.Type == "" {
l.Type = models.ListTypePrivate
}
if l.Optin == "" {
l.Optin = models.ListOptinSingle
}
// Insert and read ID.
var newID int
l.UUID = uu.String()
if err := c.q.CreateList.Get(&newID, l.UUID, l.Name, l.Type, l.Optin, pq.StringArray(normalizeTags(l.Tags)), l.Description); err != nil {
c.log.Printf("error creating list: %v", err)
return models.List{}, echo.NewHTTPError(http.StatusInternalServerError,
c.i18n.Ts("globals.messages.errorCreating", "name", "{globals.terms.list}", "error", pqErrMsg(err)))
}
return c.GetList(newID, "")
}
// UpdateList updates a given list.
func (c *Core) UpdateList(id int, l models.List) (models.List, error) {
res, err := c.q.UpdateList.Exec(id, l.Name, l.Type, l.Optin, pq.StringArray(normalizeTags(l.Tags)), l.Description)
if err != nil {
c.log.Printf("error updating list: %v", err)
return models.List{}, echo.NewHTTPError(http.StatusInternalServerError,
c.i18n.Ts("globals.messages.errorUpdating", "name", "{globals.terms.list}", "error", pqErrMsg(err)))
}
if n, _ := res.RowsAffected(); n == 0 {
return models.List{}, echo.NewHTTPError(http.StatusBadRequest,
c.i18n.Ts("globals.messages.notFound", "name", "{globals.terms.list}"))
}
return c.GetList(id, "")
}
// DeleteList deletes a list.
func (c *Core) DeleteList(id int) error {
return c.DeleteLists([]int{id})
}
// DeleteLists deletes multiple lists.
func (c *Core) DeleteLists(ids []int) error {
if _, err := c.q.DeleteLists.Exec(pq.Array(ids)); err != nil {
c.log.Printf("error deleting lists: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError,
c.i18n.Ts("globals.messages.errorDeleting", "name", "{globals.terms.list}", "error", pqErrMsg(err)))
}
return nil
}