From 40ae9cdb311e93454c1ed7cbdc0a73d8e9cebff9 Mon Sep 17 00:00:00 2001 From: Kailash Nadh Date: Sun, 8 Mar 2020 00:35:34 +0530 Subject: [PATCH] Minor formatting fixes --- init.go | 4 +- internal/manager/manager.go | 79 +++++++++++++++----------------- internal/subimporter/importer.go | 14 ++---- media.go | 28 +++++++++++ utils.go | 34 +------------- 5 files changed, 73 insertions(+), 86 deletions(-) diff --git a/init.go b/init.go index 699f30c..a7f69ed 100644 --- a/init.go +++ b/init.go @@ -186,7 +186,7 @@ func initImporter(app *App) *subimporter.Importer { } // initMessengers initializes various messaging backends. -func initMessengers(r *manager.Manager) messenger.Messenger { +func initMessengers(m *manager.Manager) messenger.Messenger { // Load SMTP configurations for the default e-mail Messenger. var ( mapKeys = ko.MapKeys("smtp") @@ -215,7 +215,7 @@ func initMessengers(r *manager.Manager) messenger.Messenger { if err != nil { lo.Fatalf("error loading e-mail messenger: %v", err) } - if err := r.AddMessenger(msgr); err != nil { + if err := m.AddMessenger(msgr); err != nil { lo.Printf("error registering messenger %s", err) } diff --git a/internal/manager/manager.go b/internal/manager/manager.go index 4c816fc..f7b14db 100644 --- a/internal/manager/manager.go +++ b/internal/manager/manager.go @@ -122,7 +122,6 @@ func (m *Manager) AddMessenger(msg messenger.Messenger) error { return fmt.Errorf("messenger '%s' is already loaded", id) } m.messengers[id] = msg - return nil } @@ -132,7 +131,6 @@ func (m *Manager) GetMessengerNames() []string { for n := range m.messengers { names = append(names, n) } - return names } @@ -196,9 +194,7 @@ func (m *Manager) Run(tick time.Duration) { delete(m.msgErrorCounts, e.camp.ID) // Notify admins. - m.sendNotif(e.camp, - models.CampaignStatusPaused, - "Too many errors") + m.sendNotif(e.camp, models.CampaignStatusPaused, "Too many errors") } } } @@ -256,6 +252,34 @@ func (m *Manager) SpawnWorkers() { } } +// TemplateFuncs returns the template functions to be applied into +// compiled campaign templates. +func (m *Manager) TemplateFuncs(c *models.Campaign) template.FuncMap { + return template.FuncMap{ + "TrackLink": func(url string, msg *Message) string { + return m.trackLink(url, msg.Campaign.UUID, msg.Subscriber.UUID) + }, + "TrackView": func(msg *Message) template.HTML { + return template.HTML(fmt.Sprintf(``, + fmt.Sprintf(m.cfg.ViewTrackURL, msg.Campaign.UUID, msg.Subscriber.UUID))) + }, + "UnsubscribeURL": func(msg *Message) string { + return msg.unsubURL + }, + "OptinURL": func(msg *Message) string { + // Add list IDs. + // TODO: Show private lists list on optin e-mail + return fmt.Sprintf(m.cfg.OptinURL, msg.Subscriber.UUID, "") + }, + "Date": func(layout string) string { + if layout == "" { + layout = time.ANSIC + } + return time.Now().Format(layout) + }, + } +} + // addCampaign adds a campaign to the process queue. func (m *Manager) addCampaign(c *models.Campaign) error { // Validate messenger. @@ -281,7 +305,6 @@ func (m *Manager) getPendingCampaignIDs() []int64 { for _, c := range m.camps { ids = append(ids, int64(c.ID)) } - return ids } @@ -358,17 +381,6 @@ func (m *Manager) exhaustCampaign(c *models.Campaign, status string) (*models.Ca return cm, nil } -// Render takes a Message, executes its pre-compiled Campaign.Tpl -// and applies the resultant bytes to Message.body to be used in messages. -func (m *Message) Render() error { - out := bytes.Buffer{} - if err := m.Campaign.Tpl.ExecuteTemplate(&out, models.BaseTpl, m); err != nil { - return err - } - m.Body = out.Bytes() - return nil -} - // trackLink register a URL and return its UUID to be used in message templates // for tracking links. func (m *Manager) trackLink(url, campUUID, subUUID string) string { @@ -412,30 +424,13 @@ func (m *Manager) sendNotif(c *models.Campaign, status, reason string) error { return m.notifCB(subject, data) } -// TemplateFuncs returns the template functions to be applied into -// compiled campaign templates. -func (m *Manager) TemplateFuncs(c *models.Campaign) template.FuncMap { - return template.FuncMap{ - "TrackLink": func(url string, msg *Message) string { - return m.trackLink(url, msg.Campaign.UUID, msg.Subscriber.UUID) - }, - "TrackView": func(msg *Message) template.HTML { - return template.HTML(fmt.Sprintf(``, - fmt.Sprintf(m.cfg.ViewTrackURL, msg.Campaign.UUID, msg.Subscriber.UUID))) - }, - "UnsubscribeURL": func(msg *Message) string { - return msg.unsubURL - }, - "OptinURL": func(msg *Message) string { - // Add list IDs. - // TODO: Show private lists list on optin e-mail - return fmt.Sprintf(m.cfg.OptinURL, msg.Subscriber.UUID, "") - }, - "Date": func(layout string) string { - if layout == "" { - layout = time.ANSIC - } - return time.Now().Format(layout) - }, +// Render takes a Message, executes its pre-compiled Campaign.Tpl +// and applies the resultant bytes to Message.body to be used in messages. +func (m *Message) Render() error { + out := bytes.Buffer{} + if err := m.Campaign.Tpl.ExecuteTemplate(&out, models.BaseTpl, m); err != nil { + return err } + m.Body = out.Bytes() + return nil } diff --git a/internal/subimporter/importer.go b/internal/subimporter/importer.go index 0f60238..b329eed 100644 --- a/internal/subimporter/importer.go +++ b/internal/subimporter/importer.go @@ -21,11 +21,10 @@ import ( "strings" "sync" - "github.com/gofrs/uuid" - "github.com/lib/pq" - "github.com/asaskevich/govalidator" + "github.com/gofrs/uuid" "github.com/knadh/listmonk/models" + "github.com/lib/pq" ) const ( @@ -34,7 +33,10 @@ const ( // commitBatchSize is the number of inserts to commit in a single SQL transaction. commitBatchSize = 10000 +) +// Various import statuses. +const ( StatusNone = "none" StatusImporting = "importing" StatusStopping = "stopping" @@ -113,7 +115,6 @@ func New(upsert *sql.Stmt, blacklist *sql.Stmt, updateListDate *sql.Stmt, notifCB: notifCB, status: Status{Status: StatusNone, logBuf: bytes.NewBuffer(nil)}, } - return &im } @@ -162,7 +163,6 @@ func (im *Importer) GetLogs() []byte { if im.status.logBuf == nil { return []byte{} } - return im.status.logBuf.Bytes() } @@ -213,7 +213,6 @@ func (im *Importer) sendNotif(status string) error { strings.Title(status), s.Name) ) - return im.notifCB(subject, out) } @@ -526,7 +525,6 @@ func (s *Session) LoadCSV(srcPath string, delim rune) error { close(s.subQueue) failed = false - return nil } @@ -558,7 +556,6 @@ func (s *Session) mapCSVHeaders(csvHdrs []string, knownHdrs map[string]bool) map s.log.Printf("ignoring unknown header '%s'", h) continue } - hdrKeys[h] = i } @@ -601,5 +598,4 @@ func countLines(r io.Reader) (int, error) { return count, err } } - } diff --git a/media.go b/media.go index a07ee3d..20723c9 100644 --- a/media.go +++ b/media.go @@ -1,10 +1,13 @@ package main import ( + "bytes" "fmt" + "mime/multipart" "net/http" "strconv" + "github.com/disintegration/imaging" "github.com/gofrs/uuid" "github.com/knadh/listmonk/internal/media" "github.com/labstack/echo" @@ -146,3 +149,28 @@ func handleDeleteMedia(c echo.Context) error { app.media.Delete(thumbPrefix + m.Filename) return c.JSON(http.StatusOK, okResp{true}) } + +// createThumbnail reads the file object and returns a smaller image +func createThumbnail(file *multipart.FileHeader) (*bytes.Reader, error) { + src, err := file.Open() + if err != nil { + return nil, err + } + defer src.Close() + + img, err := imaging.Decode(src) + if err != nil { + return nil, echo.NewHTTPError(http.StatusInternalServerError, + fmt.Sprintf("Error decoding image: %v", err)) + } + + // Encode the image into a byte slice as PNG. + var ( + thumb = imaging.Resize(img, thumbnailSize, 0, imaging.Lanczos) + out bytes.Buffer + ) + if err := imaging.Encode(&out, thumb, imaging.PNG); err != nil { + return nil, err + } + return bytes.NewReader(out.Bytes()), nil +} diff --git a/utils.go b/utils.go index b752871..4bf914c 100644 --- a/utils.go +++ b/utils.go @@ -4,15 +4,10 @@ import ( "bytes" "crypto/rand" "fmt" - "log" - "mime/multipart" - "net/http" "regexp" "strconv" "strings" - "github.com/disintegration/imaging" - "github.com/labstack/echo" "github.com/lib/pq" ) @@ -52,28 +47,6 @@ func generateFileName(fName string) string { return name } -// createThumbnail reads the file object and returns a smaller image -func createThumbnail(file *multipart.FileHeader) (*bytes.Reader, error) { - src, err := file.Open() - if err != nil { - return nil, err - } - defer src.Close() - img, err := imaging.Decode(src) - if err != nil { - return nil, echo.NewHTTPError(http.StatusInternalServerError, - fmt.Sprintf("Error decoding image: %v", err)) - } - t := imaging.Resize(img, thumbnailSize, 0, imaging.Lanczos) - // Encode the image into a byte slice as PNG. - var buf bytes.Buffer - err = imaging.Encode(&buf, t, imaging.PNG) - if err != nil { - log.Fatal(err) - } - return bytes.NewReader(buf.Bytes()), nil -} - // Given an error, pqErrMsg will try to return pq error details // if it's a pq error. func pqErrMsg(err error) string { @@ -82,7 +55,6 @@ func pqErrMsg(err error) string { return fmt.Sprintf("%s. %s", err, err.Detail) } } - return err.Error() } @@ -103,7 +75,6 @@ func normalizeTags(tags []string) []string { out = append(out, string(rep)) } } - return out } @@ -118,7 +89,6 @@ func makeMsgTpl(pageTitle, heading, msg string) msgTpl { err.Title = pageTitle err.MessageTitle = heading err.Message = msg - return err } @@ -127,7 +97,6 @@ func makeMsgTpl(pageTitle, heading, msg string) msgTpl { // resultant values. func parseStringIDs(s []string) ([]int64, error) { vals := make([]int64, 0, len(s)) - for _, v := range s { i, err := strconv.ParseInt(v, 10, 64) if err != nil { @@ -147,12 +116,11 @@ func parseStringIDs(s []string) ([]int64, error) { // generateRandomString generates a cryptographically random, alphanumeric string of length n. func generateRandomString(n int) (string, error) { const dictionary = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" - var bytes = make([]byte, n) + if _, err := rand.Read(bytes); err != nil { return "", err } - for k, v := range bytes { bytes[k] = dictionary[v%byte(len(dictionary))] }