Refactor and remove placeholder i18n func

This commit is contained in:
Kailash Nadh 2021-01-23 18:54:33 +05:30
parent 810607e547
commit 4cd5e6ebeb
11 changed files with 121 additions and 153 deletions

View File

@ -72,9 +72,7 @@ func handleGetConfigScript(c echo.Context) error {
j := json.NewEncoder(&b) j := json.NewEncoder(&b)
if err := j.Encode(out); err != nil { if err := j.Encode(out); err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts("admin.errorMarshallingConfig", map[string]string{ app.i18n.Ts("admin.errorMarshallingConfig", "error", err.Error()))
"error": err.Error(),
}))
} }
return c.Blob(http.StatusOK, "application/javascript; charset=utf-8", b.Bytes()) return c.Blob(http.StatusOK, "application/javascript; charset=utf-8", b.Bytes())
} }
@ -88,10 +86,7 @@ func handleGetDashboardCharts(c echo.Context) error {
if err := app.queries.GetDashboardCharts.Get(&out); err != nil { if err := app.queries.GetDashboardCharts.Get(&out); err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts("globals.messages.errorFetching", map[string]string{ app.i18n.Ts("globals.messages.errorFetching", "name", "dashboard charts", "error", pqErrMsg(err)))
"name": "dashboard charts",
"error": pqErrMsg(err),
}))
} }
return c.JSON(http.StatusOK, okResp{out}) return c.JSON(http.StatusOK, okResp{out})
@ -106,10 +101,7 @@ func handleGetDashboardCounts(c echo.Context) error {
if err := app.queries.GetDashboardCounts.Get(&out); err != nil { if err := app.queries.GetDashboardCounts.Get(&out); err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts("globals.messages.errorFetching", map[string]string{ app.i18n.Ts("globals.messages.errorFetching", "name", "dashboard stats", "error", pqErrMsg(err)))
"name": "dashboard stats",
"error": pqErrMsg(err),
}))
} }
return c.JSON(http.StatusOK, okResp{out}) return c.JSON(http.StatusOK, okResp{out})

View File

@ -106,12 +106,12 @@ func handleGetCampaigns(c echo.Context) error {
if err := db.Select(&out.Results, stmt, id, pq.StringArray(status), query, pg.Offset, pg.Limit); err != nil { if err := db.Select(&out.Results, stmt, id, pq.StringArray(status), query, pg.Offset, pg.Limit); err != nil {
app.log.Printf("error fetching campaigns: %v", err) app.log.Printf("error fetching campaigns: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorFetching", app.i18n.Ts("globals.messages.errorFetching",
"name", "{globals.terms.campaign}", "error", pqErrMsg(err))) "name", "{globals.terms.campaign}", "error", pqErrMsg(err)))
} }
if single && len(out.Results) == 0 { if single && len(out.Results) == 0 {
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
app.i18n.Ts2("campaigns.notFound", "name", "{globals.terms.campaign}")) app.i18n.Ts("campaigns.notFound", "name", "{globals.terms.campaign}"))
} }
if len(out.Results) == 0 { if len(out.Results) == 0 {
out.Results = []models.Campaign{} out.Results = []models.Campaign{}
@ -133,7 +133,7 @@ func handleGetCampaigns(c echo.Context) error {
if err := out.Results.LoadStats(app.queries.GetCampaignStats); err != nil { if err := out.Results.LoadStats(app.queries.GetCampaignStats); err != nil {
app.log.Printf("error fetching campaign stats: %v", err) app.log.Printf("error fetching campaign stats: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorFetching", app.i18n.Ts("globals.messages.errorFetching",
"name", "{globals.terms.campaign}", "error", pqErrMsg(err))) "name", "{globals.terms.campaign}", "error", pqErrMsg(err)))
} }
@ -167,12 +167,12 @@ func handlePreviewCampaign(c echo.Context) error {
if err != nil { if err != nil {
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
app.i18n.Ts2("globals.messages.notFound", "name", "{globals.terms.campaign}")) app.i18n.Ts("globals.messages.notFound", "name", "{globals.terms.campaign}"))
} }
app.log.Printf("error fetching campaign: %v", err) app.log.Printf("error fetching campaign: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorFetching", app.i18n.Ts("globals.messages.errorFetching",
"name", "{globals.terms.campaign}", "error", pqErrMsg(err))) "name", "{globals.terms.campaign}", "error", pqErrMsg(err)))
} }
@ -185,7 +185,7 @@ func handlePreviewCampaign(c echo.Context) error {
} else { } else {
app.log.Printf("error fetching subscriber: %v", err) app.log.Printf("error fetching subscriber: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorFetching", app.i18n.Ts("globals.messages.errorFetching",
"name", "{globals.terms.subscriber}", "error", pqErrMsg(err))) "name", "{globals.terms.subscriber}", "error", pqErrMsg(err)))
} }
} }
@ -198,7 +198,7 @@ func handlePreviewCampaign(c echo.Context) error {
if err := camp.CompileTemplate(app.manager.TemplateFuncs(camp)); err != nil { if err := camp.CompileTemplate(app.manager.TemplateFuncs(camp)); err != nil {
app.log.Printf("error compiling template: %v", err) app.log.Printf("error compiling template: %v", err)
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
app.i18n.Ts2("templates.errorCompiling", "error", err.Error())) app.i18n.Ts("templates.errorCompiling", "error", err.Error()))
} }
// Render the message body. // Render the message body.
@ -206,7 +206,7 @@ func handlePreviewCampaign(c echo.Context) error {
if err := m.Render(); err != nil { if err := m.Render(); err != nil {
app.log.Printf("error rendering message: %v", err) app.log.Printf("error rendering message: %v", err)
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
app.i18n.Ts2("templates.errorRendering", "error", err.Error())) app.i18n.Ts("templates.errorRendering", "error", err.Error()))
} }
return c.HTML(http.StatusOK, string(m.Body())) return c.HTML(http.StatusOK, string(m.Body()))
@ -244,7 +244,7 @@ func handleCreateCampaign(c echo.Context) error {
if err != nil { if err != nil {
app.log.Printf("error generating UUID: %v", err) app.log.Printf("error generating UUID: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorUUID", "error", err.Error())) app.i18n.Ts("globals.messages.errorUUID", "error", err.Error()))
} }
// Insert and read ID. // Insert and read ID.
@ -269,7 +269,7 @@ func handleCreateCampaign(c echo.Context) error {
app.log.Printf("error creating campaign: %v", err) app.log.Printf("error creating campaign: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorCreating", app.i18n.Ts("globals.messages.errorCreating",
"name", "{globals.terms.campaign}", "error", pqErrMsg(err))) "name", "{globals.terms.campaign}", "error", pqErrMsg(err)))
} }
@ -296,12 +296,12 @@ func handleUpdateCampaign(c echo.Context) error {
if err := app.queries.GetCampaign.Get(&cm, id, nil); err != nil { if err := app.queries.GetCampaign.Get(&cm, id, nil); err != nil {
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.notFound", "name", "{globals.terms.campaign}")) app.i18n.Ts("globals.messages.notFound", "name", "{globals.terms.campaign}"))
} }
app.log.Printf("error fetching campaign: %v", err) app.log.Printf("error fetching campaign: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorFetching", app.i18n.Ts("globals.messages.errorFetching",
"name", "{globals.terms.campaign}", "error", pqErrMsg(err))) "name", "{globals.terms.campaign}", "error", pqErrMsg(err)))
} }
@ -336,7 +336,7 @@ func handleUpdateCampaign(c echo.Context) error {
if err != nil { if err != nil {
app.log.Printf("error updating campaign: %v", err) app.log.Printf("error updating campaign: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorUpdating", app.i18n.Ts("globals.messages.errorUpdating",
"name", "{globals.terms.campaign}", "error", pqErrMsg(err))) "name", "{globals.terms.campaign}", "error", pqErrMsg(err)))
} }
@ -358,15 +358,12 @@ func handleUpdateCampaignStatus(c echo.Context) error {
if err := app.queries.GetCampaign.Get(&cm, id, nil); err != nil { if err := app.queries.GetCampaign.Get(&cm, id, nil); err != nil {
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
app.i18n.Ts("", map[string]string{ app.i18n.Ts("globals.message.notFound", "name", "{globals.terms.campaign}"))
"name": "{globals.terms.campaign}",
}))
} }
app.log.Printf("error fetching campaign: %v", err) app.log.Printf("error fetching campaign: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorFetching", app.i18n.Ts("globals.messages.errorFetching",
"name", "{globals.terms.campaign}", "error", pqErrMsg(err))) "name", "{globals.terms.campaign}", "error", pqErrMsg(err)))
} }
@ -413,13 +410,13 @@ func handleUpdateCampaignStatus(c echo.Context) error {
app.log.Printf("error updating campaign status: %v", err) app.log.Printf("error updating campaign status: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorUpdating", app.i18n.Ts("globals.messages.errorUpdating",
"name", "{globals.terms.campaign}", "error", pqErrMsg(err))) "name", "{globals.terms.campaign}", "error", pqErrMsg(err)))
} }
if n, _ := res.RowsAffected(); n == 0 { if n, _ := res.RowsAffected(); n == 0 {
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
app.i18n.Ts2("globals.messages.notFound", app.i18n.Ts("globals.messages.notFound",
"name", "{globals.terms.campaign}", "error", pqErrMsg(err))) "name", "{globals.terms.campaign}", "error", pqErrMsg(err)))
} }
@ -442,20 +439,20 @@ func handleDeleteCampaign(c echo.Context) error {
if err := app.queries.GetCampaign.Get(&cm, id, nil); err != nil { if err := app.queries.GetCampaign.Get(&cm, id, nil); err != nil {
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
app.i18n.Ts2("globals.messages.notFound", app.i18n.Ts("globals.messages.notFound",
"name", "{globals.terms.campaign}", "error", pqErrMsg(err))) "name", "{globals.terms.campaign}", "error", pqErrMsg(err)))
} }
app.log.Printf("error fetching campaign: %v", err) app.log.Printf("error fetching campaign: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorFetching", app.i18n.Ts("globals.messages.errorFetching",
"name", "{globals.terms.campaign}", "error", pqErrMsg(err))) "name", "{globals.terms.campaign}", "error", pqErrMsg(err)))
} }
if _, err := app.queries.DeleteCampaign.Exec(cm.ID); err != nil { if _, err := app.queries.DeleteCampaign.Exec(cm.ID); err != nil {
app.log.Printf("error deleting campaign: %v", err) app.log.Printf("error deleting campaign: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorDeleting", app.i18n.Ts("globals.messages.errorDeleting",
"name", "{globals.terms.campaign}", "error", pqErrMsg(err))) "name", "{globals.terms.campaign}", "error", pqErrMsg(err)))
} }
@ -477,7 +474,7 @@ func handleGetRunningCampaignStats(c echo.Context) error {
app.log.Printf("error fetching campaign stats: %v", err) app.log.Printf("error fetching campaign stats: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorFetching", app.i18n.Ts("globals.messages.errorFetching",
"name", "{globals.terms.campaign}", "error", pqErrMsg(err))) "name", "{globals.terms.campaign}", "error", pqErrMsg(err)))
} else if len(out) == 0 { } else if len(out) == 0 {
return c.JSON(http.StatusOK, okResp{[]struct{}{}}) return c.JSON(http.StatusOK, okResp{[]struct{}{}})
@ -539,7 +536,7 @@ func handleTestCampaign(c echo.Context) error {
if err := app.queries.GetSubscribersByEmails.Select(&subs, req.SubscriberEmails); err != nil { if err := app.queries.GetSubscribersByEmails.Select(&subs, req.SubscriberEmails); err != nil {
app.log.Printf("error fetching subscribers: %v", err) app.log.Printf("error fetching subscribers: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorFetching", app.i18n.Ts("globals.messages.errorFetching",
"name", "{globals.terms.subscribers}", "error", pqErrMsg(err))) "name", "{globals.terms.subscribers}", "error", pqErrMsg(err)))
} else if len(subs) == 0 { } else if len(subs) == 0 {
return echo.NewHTTPError(http.StatusBadRequest, app.i18n.T("campaigns.noKnownSubsToTest")) return echo.NewHTTPError(http.StatusBadRequest, app.i18n.T("campaigns.noKnownSubsToTest"))
@ -550,13 +547,13 @@ func handleTestCampaign(c echo.Context) error {
if err := app.queries.GetCampaignForPreview.Get(&camp, campID); err != nil { if err := app.queries.GetCampaignForPreview.Get(&camp, campID); err != nil {
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
app.i18n.Ts2("globals.messages.notFound", app.i18n.Ts("globals.messages.notFound",
"name", "{globals.terms.campaign}")) "name", "{globals.terms.campaign}"))
} }
app.log.Printf("error fetching campaign: %v", err) app.log.Printf("error fetching campaign: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorFetching", app.i18n.Ts("globals.messages.errorFetching",
"name", "{globals.terms.campaign}", "error", pqErrMsg(err))) "name", "{globals.terms.campaign}", "error", pqErrMsg(err)))
} }
@ -574,7 +571,7 @@ func handleTestCampaign(c echo.Context) error {
sub := s sub := s
if err := sendTestMessage(sub, &camp, app); err != nil { if err := sendTestMessage(sub, &camp, app); err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("campaigns.errorSendTest", "error", err.Error())) app.i18n.Ts("campaigns.errorSendTest", "error", err.Error()))
} }
} }
@ -586,7 +583,7 @@ func sendTestMessage(sub models.Subscriber, camp *models.Campaign, app *App) err
if err := camp.CompileTemplate(app.manager.TemplateFuncs(camp)); err != nil { if err := camp.CompileTemplate(app.manager.TemplateFuncs(camp)); err != nil {
app.log.Printf("error compiling template: %v", err) app.log.Printf("error compiling template: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("templates.errorCompiling", "error", err.Error())) app.i18n.Ts("templates.errorCompiling", "error", err.Error()))
} }
// Render the message body. // Render the message body.
@ -594,7 +591,7 @@ func sendTestMessage(sub models.Subscriber, camp *models.Campaign, app *App) err
if err := m.Render(); err != nil { if err := m.Render(); err != nil {
app.log.Printf("error rendering message: %v", err) app.log.Printf("error rendering message: %v", err)
return echo.NewHTTPError(http.StatusNotFound, return echo.NewHTTPError(http.StatusNotFound,
app.i18n.Ts2("templates.errorRendering", "error", err.Error())) app.i18n.Ts("templates.errorRendering", "error", err.Error()))
} }
return app.messengers[camp.Messenger].Push(messenger.Message{ return app.messengers[camp.Messenger].Push(messenger.Message{
@ -641,12 +638,12 @@ func validateCampaignFields(c campaignReq, app *App) (campaignReq, error) {
} }
if !app.manager.HasMessenger(c.Messenger) { if !app.manager.HasMessenger(c.Messenger) {
return c, errors.New(app.i18n.Ts2("campaigns.fieldInvalidMessenger", "name", c.Messenger)) return c, errors.New(app.i18n.Ts("campaigns.fieldInvalidMessenger", "name", c.Messenger))
} }
camp := models.Campaign{Body: c.Body, TemplateBody: tplTag} camp := models.Campaign{Body: c.Body, TemplateBody: tplTag}
if err := c.CompileTemplate(app.manager.TemplateFuncs(&camp)); err != nil { if err := c.CompileTemplate(app.manager.TemplateFuncs(&camp)); err != nil {
return c, errors.New(app.i18n.Ts2("campaigns.fieldInvalidBody", "error", err.Error())) return c, errors.New(app.i18n.Ts("campaigns.fieldInvalidBody", "error", err.Error()))
} }
return c, nil return c, nil
@ -672,7 +669,7 @@ func makeOptinCampaignMessage(o campaignReq, app *App) (campaignReq, error) {
if err != nil { if err != nil {
app.log.Printf("error fetching lists for opt-in: %s", pqErrMsg(err)) app.log.Printf("error fetching lists for opt-in: %s", pqErrMsg(err))
return o, echo.NewHTTPError(http.StatusInternalServerError, return o, echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorFetching", app.i18n.Ts("globals.messages.errorFetching",
"name", "{globals.terms.list}", "error", pqErrMsg(err))) "name", "{globals.terms.list}", "error", pqErrMsg(err)))
} }
@ -697,7 +694,7 @@ func makeOptinCampaignMessage(o campaignReq, app *App) (campaignReq, error) {
}{lists, optinURLAttr}); err != nil { }{lists, optinURLAttr}); err != nil {
app.log.Printf("error compiling 'optin-campaign' template: %v", err) app.log.Printf("error compiling 'optin-campaign' template: %v", err)
return o, echo.NewHTTPError(http.StatusBadRequest, return o, echo.NewHTTPError(http.StatusBadRequest,
app.i18n.Ts2("templates.errorCompiling", "error", err.Error())) app.i18n.Ts("templates.errorCompiling", "error", err.Error()))
} }
o.Body = b.String() o.Body = b.String()

View File

@ -33,7 +33,7 @@ func handleImportSubscribers(c echo.Context) error {
var r reqImport var r reqImport
if err := json.Unmarshal([]byte(c.FormValue("params")), &r); err != nil { if err := json.Unmarshal([]byte(c.FormValue("params")), &r); err != nil {
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
app.i18n.Ts2("import.invalidParams", "error", err.Error())) app.i18n.Ts("import.invalidParams", "error", err.Error()))
} }
if r.Mode != subimporter.ModeSubscribe && r.Mode != subimporter.ModeBlocklist { if r.Mode != subimporter.ModeSubscribe && r.Mode != subimporter.ModeBlocklist {
@ -47,7 +47,7 @@ func handleImportSubscribers(c echo.Context) error {
file, err := c.FormFile("file") file, err := c.FormFile("file")
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
app.i18n.Ts2("import.invalidFile", "error", err.Error())) app.i18n.Ts("import.invalidFile", "error", err.Error()))
} }
src, err := file.Open() src, err := file.Open()
@ -59,20 +59,20 @@ func handleImportSubscribers(c echo.Context) error {
out, err := ioutil.TempFile("", "listmonk") out, err := ioutil.TempFile("", "listmonk")
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("import.errorCopyingFile", "error", err.Error())) app.i18n.Ts("import.errorCopyingFile", "error", err.Error()))
} }
defer out.Close() defer out.Close()
if _, err = io.Copy(out, src); err != nil { if _, err = io.Copy(out, src); err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("import.errorCopyingFile", "error", err.Error())) app.i18n.Ts("import.errorCopyingFile", "error", err.Error()))
} }
// Start the importer session. // Start the importer session.
impSess, err := app.importer.NewSession(file.Filename, r.Mode, r.Overwrite, r.ListIDs) impSess, err := app.importer.NewSession(file.Filename, r.Mode, r.Overwrite, r.ListIDs)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("import.errorStarting", "error", err.Error())) app.i18n.Ts("import.errorStarting", "error", err.Error()))
} }
go impSess.Start() go impSess.Start()
@ -88,7 +88,7 @@ func handleImportSubscribers(c echo.Context) error {
dir, files, err := impSess.ExtractZIP(out.Name(), 1) dir, files, err := impSess.ExtractZIP(out.Name(), 1)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("import.errorProcessingZIP", "error", err.Error())) app.i18n.Ts("import.errorProcessingZIP", "error", err.Error()))
} }
go impSess.LoadCSV(dir+"/"+files[0], rune(r.Delim[0])) go impSess.LoadCSV(dir+"/"+files[0], rune(r.Delim[0]))
} }

View File

@ -53,12 +53,12 @@ func handleGetLists(c echo.Context) error {
if err := db.Select(&out.Results, fmt.Sprintf(app.queries.GetLists, orderBy, order), listID, pg.Offset, pg.Limit); err != nil { if err := db.Select(&out.Results, fmt.Sprintf(app.queries.GetLists, orderBy, order), listID, pg.Offset, pg.Limit); err != nil {
app.log.Printf("error fetching lists: %v", err) app.log.Printf("error fetching lists: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorFetching", app.i18n.Ts("globals.messages.errorFetching",
"name", "{globals.terms.lists}", "error", pqErrMsg(err))) "name", "{globals.terms.lists}", "error", pqErrMsg(err)))
} }
if single && len(out.Results) == 0 { if single && len(out.Results) == 0 {
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
app.i18n.Ts2("globals.messages.notFound", "name", "{globals.terms.list}")) app.i18n.Ts("globals.messages.notFound", "name", "{globals.terms.list}"))
} }
if len(out.Results) == 0 { if len(out.Results) == 0 {
return c.JSON(http.StatusOK, okResp{[]struct{}{}}) return c.JSON(http.StatusOK, okResp{[]struct{}{}})
@ -102,7 +102,7 @@ func handleCreateList(c echo.Context) error {
if err != nil { if err != nil {
app.log.Printf("error generating UUID: %v", err) app.log.Printf("error generating UUID: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts("globals.messages.errorUUID", map[string]string{"error": err.Error()})) app.i18n.Ts("globals.messages.errorUUID", "error", err.Error()))
} }
// Insert and read ID. // Insert and read ID.
@ -116,7 +116,7 @@ func handleCreateList(c echo.Context) error {
pq.StringArray(normalizeTags(o.Tags))); err != nil { pq.StringArray(normalizeTags(o.Tags))); err != nil {
app.log.Printf("error creating list: %v", err) app.log.Printf("error creating list: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorCreating", app.i18n.Ts("globals.messages.errorCreating",
"name", "{globals.terms.list}", "error", pqErrMsg(err))) "name", "{globals.terms.list}", "error", pqErrMsg(err)))
} }
@ -148,13 +148,13 @@ func handleUpdateList(c echo.Context) error {
if err != nil { if err != nil {
app.log.Printf("error updating list: %v", err) app.log.Printf("error updating list: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorUpdating", app.i18n.Ts("globals.messages.errorUpdating",
"name", "{globals.terms.list}", "error", pqErrMsg(err))) "name", "{globals.terms.list}", "error", pqErrMsg(err)))
} }
if n, _ := res.RowsAffected(); n == 0 { if n, _ := res.RowsAffected(); n == 0 {
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
app.i18n.Ts2("globals.messages.notFound", "name", "{globals.terms.list}")) app.i18n.Ts("globals.messages.notFound", "name", "{globals.terms.list}"))
} }
return handleGetLists(c) return handleGetLists(c)
@ -180,7 +180,7 @@ func handleDeleteLists(c echo.Context) error {
if _, err := app.queries.DeleteLists.Exec(ids); err != nil { if _, err := app.queries.DeleteLists.Exec(ids); err != nil {
app.log.Printf("error deleting lists: %v", err) app.log.Printf("error deleting lists: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorDeleting", app.i18n.Ts("globals.messages.errorDeleting",
"name", "{globals.terms.list}", "error", pqErrMsg(err))) "name", "{globals.terms.list}", "error", pqErrMsg(err)))
} }

View File

@ -34,14 +34,14 @@ func handleUploadMedia(c echo.Context) error {
file, err := c.FormFile("file") file, err := c.FormFile("file")
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
app.i18n.Ts2("media.invalidFile", "error", err.Error())) app.i18n.Ts("media.invalidFile", "error", err.Error()))
} }
// Validate MIME type with the list of allowed types. // Validate MIME type with the list of allowed types.
var typ = file.Header.Get("Content-type") var typ = file.Header.Get("Content-type")
if ok := validateMIME(typ, imageMimes); !ok { if ok := validateMIME(typ, imageMimes); !ok {
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
app.i18n.Ts2("media.unsupportedFileType", "type", typ)) app.i18n.Ts("media.unsupportedFileType", "type", typ))
} }
// Generate filename // Generate filename
@ -51,7 +51,7 @@ func handleUploadMedia(c echo.Context) error {
src, err := file.Open() src, err := file.Open()
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("media.errorReadingFile", "error", err.Error())) app.i18n.Ts("media.errorReadingFile", "error", err.Error()))
} }
defer src.Close() defer src.Close()
@ -61,7 +61,7 @@ func handleUploadMedia(c echo.Context) error {
app.log.Printf("error uploading file: %v", err) app.log.Printf("error uploading file: %v", err)
cleanUp = true cleanUp = true
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("media.errorUploading", "error", err.Error())) app.i18n.Ts("media.errorUploading", "error", err.Error()))
} }
defer func() { defer func() {
@ -79,7 +79,7 @@ func handleUploadMedia(c echo.Context) error {
cleanUp = true cleanUp = true
app.log.Printf("error resizing image: %v", err) app.log.Printf("error resizing image: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("media.errorResizing", "error", err.Error())) app.i18n.Ts("media.errorResizing", "error", err.Error()))
} }
// Upload thumbnail. // Upload thumbnail.
@ -88,14 +88,14 @@ func handleUploadMedia(c echo.Context) error {
cleanUp = true cleanUp = true
app.log.Printf("error saving thumbnail: %v", err) app.log.Printf("error saving thumbnail: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("media.errorSavingThumbnail", "error", err.Error())) app.i18n.Ts("media.errorSavingThumbnail", "error", err.Error()))
} }
uu, err := uuid.NewV4() uu, err := uuid.NewV4()
if err != nil { if err != nil {
app.log.Printf("error generating UUID: %v", err) app.log.Printf("error generating UUID: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorUUID", "error", err.Error())) app.i18n.Ts("globals.messages.errorUUID", "error", err.Error()))
} }
// Write to the DB. // Write to the DB.
@ -103,7 +103,7 @@ func handleUploadMedia(c echo.Context) error {
cleanUp = true cleanUp = true
app.log.Printf("error inserting uploaded file to db: %v", err) app.log.Printf("error inserting uploaded file to db: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorCreating", app.i18n.Ts("globals.messages.errorCreating",
"name", "{globals.terms.media}", "error", pqErrMsg(err))) "name", "{globals.terms.media}", "error", pqErrMsg(err)))
} }
return c.JSON(http.StatusOK, okResp{true}) return c.JSON(http.StatusOK, okResp{true})
@ -118,7 +118,7 @@ func handleGetMedia(c echo.Context) error {
if err := app.queries.GetMedia.Select(&out, app.constants.MediaProvider); err != nil { if err := app.queries.GetMedia.Select(&out, app.constants.MediaProvider); err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorFetching", app.i18n.Ts("globals.messages.errorFetching",
"name", "{globals.terms.media}", "error", pqErrMsg(err))) "name", "{globals.terms.media}", "error", pqErrMsg(err)))
} }
@ -144,7 +144,7 @@ func handleDeleteMedia(c echo.Context) error {
var m media.Media var m media.Media
if err := app.queries.DeleteMedia.Get(&m, id); err != nil { if err := app.queries.DeleteMedia.Get(&m, id); err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorDeleting", app.i18n.Ts("globals.messages.errorDeleting",
"name", "{globals.terms.media}", "error", pqErrMsg(err))) "name", "{globals.terms.media}", "error", pqErrMsg(err)))
} }

View File

@ -109,7 +109,7 @@ func handleViewCampaignMessage(c echo.Context) error {
app.log.Printf("error fetching campaign: %v", err) app.log.Printf("error fetching campaign: %v", err)
return c.Render(http.StatusInternalServerError, tplMessage, return c.Render(http.StatusInternalServerError, tplMessage,
makeMsgTpl(app.i18n.T("public.errorTitle"), "", makeMsgTpl(app.i18n.T("public.errorTitle"), "",
app.i18n.Ts2("public.errorFetchingCampaign"))) app.i18n.Ts("public.errorFetchingCampaign")))
} }
// Get the subscriber. // Get the subscriber.
@ -124,7 +124,7 @@ func handleViewCampaignMessage(c echo.Context) error {
app.log.Printf("error fetching campaign subscriber: %v", err) app.log.Printf("error fetching campaign subscriber: %v", err)
return c.Render(http.StatusInternalServerError, tplMessage, return c.Render(http.StatusInternalServerError, tplMessage,
makeMsgTpl(app.i18n.T("public.errorTitle"), "", makeMsgTpl(app.i18n.T("public.errorTitle"), "",
app.i18n.Ts2("public.errorFetchingCampaign"))) app.i18n.Ts("public.errorFetchingCampaign")))
} }
// Compile the template. // Compile the template.
@ -132,7 +132,7 @@ func handleViewCampaignMessage(c echo.Context) error {
app.log.Printf("error compiling template: %v", err) app.log.Printf("error compiling template: %v", err)
return c.Render(http.StatusInternalServerError, tplMessage, return c.Render(http.StatusInternalServerError, tplMessage,
makeMsgTpl(app.i18n.T("public.errorTitle"), "", makeMsgTpl(app.i18n.T("public.errorTitle"), "",
app.i18n.Ts2("public.errorFetchingCampaign"))) app.i18n.Ts("public.errorFetchingCampaign")))
} }
// Render the message body. // Render the message body.
@ -141,7 +141,7 @@ func handleViewCampaignMessage(c echo.Context) error {
app.log.Printf("error rendering message: %v", err) app.log.Printf("error rendering message: %v", err)
return c.Render(http.StatusInternalServerError, tplMessage, return c.Render(http.StatusInternalServerError, tplMessage,
makeMsgTpl(app.i18n.T("public.errorTitle"), "", makeMsgTpl(app.i18n.T("public.errorTitle"), "",
app.i18n.Ts2("public.errorFetchingCampaign"))) app.i18n.Ts("public.errorFetchingCampaign")))
} }
return c.HTML(http.StatusOK, string(m.Body())) return c.HTML(http.StatusOK, string(m.Body()))
@ -176,7 +176,7 @@ func handleSubscriptionPage(c echo.Context) error {
app.log.Printf("error unsubscribing: %v", err) app.log.Printf("error unsubscribing: %v", err)
return c.Render(http.StatusInternalServerError, tplMessage, return c.Render(http.StatusInternalServerError, tplMessage,
makeMsgTpl(app.i18n.T("public.errorTitle"), "", makeMsgTpl(app.i18n.T("public.errorTitle"), "",
app.i18n.Ts2("public.errorProcessingRequest"))) app.i18n.Ts("public.errorProcessingRequest")))
} }
return c.Render(http.StatusOK, tplMessage, return c.Render(http.StatusOK, tplMessage,
@ -224,14 +224,14 @@ func handleOptinPage(c echo.Context) error {
return c.Render(http.StatusInternalServerError, tplMessage, return c.Render(http.StatusInternalServerError, tplMessage,
makeMsgTpl(app.i18n.T("public.errorTitle"), "", makeMsgTpl(app.i18n.T("public.errorTitle"), "",
app.i18n.Ts2("public.errorFetchingLists"))) app.i18n.Ts("public.errorFetchingLists")))
} }
// There are no lists to confirm. // There are no lists to confirm.
if len(out.Lists) == 0 { if len(out.Lists) == 0 {
return c.Render(http.StatusInternalServerError, tplMessage, return c.Render(http.StatusInternalServerError, tplMessage,
makeMsgTpl(app.i18n.T("public.noSubTitle"), "", makeMsgTpl(app.i18n.T("public.noSubTitle"), "",
app.i18n.Ts2("public.noSubInfo"))) app.i18n.Ts("public.noSubInfo")))
} }
// Confirm. // Confirm.
@ -240,12 +240,12 @@ func handleOptinPage(c echo.Context) error {
app.log.Printf("error unsubscribing: %v", err) app.log.Printf("error unsubscribing: %v", err)
return c.Render(http.StatusInternalServerError, tplMessage, return c.Render(http.StatusInternalServerError, tplMessage,
makeMsgTpl(app.i18n.T("public.errorTitle"), "", makeMsgTpl(app.i18n.T("public.errorTitle"), "",
app.i18n.Ts2("public.errorProcessingRequest"))) app.i18n.Ts("public.errorProcessingRequest")))
} }
return c.Render(http.StatusOK, tplMessage, return c.Render(http.StatusOK, tplMessage,
makeMsgTpl(app.i18n.T("public.subsConfirmedTitle"), "", makeMsgTpl(app.i18n.T("public.subsConfirmedTitle"), "",
app.i18n.Ts2("public.subConfirmed"))) app.i18n.Ts("public.subConfirmed")))
} }
return c.Render(http.StatusOK, "optin", out) return c.Render(http.StatusOK, "optin", out)
@ -292,7 +292,7 @@ func handleSubscriptionForm(c echo.Context) error {
return c.Render(http.StatusOK, tplMessage, return c.Render(http.StatusOK, tplMessage,
makeMsgTpl(app.i18n.T("public.subsConfirmedTitle"), "", makeMsgTpl(app.i18n.T("public.subsConfirmedTitle"), "",
app.i18n.Ts2("public.subConfirmed"))) app.i18n.Ts("public.subConfirmed")))
} }
// handleLinkRedirect redirects a link UUID to its original underlying link // handleLinkRedirect redirects a link UUID to its original underlying link
@ -316,13 +316,13 @@ func handleLinkRedirect(c echo.Context) error {
if pqErr, ok := err.(*pq.Error); ok && pqErr.Column == "link_id" { if pqErr, ok := err.(*pq.Error); ok && pqErr.Column == "link_id" {
return c.Render(http.StatusNotFound, tplMessage, return c.Render(http.StatusNotFound, tplMessage,
makeMsgTpl(app.i18n.T("public.errorTitle"), "", makeMsgTpl(app.i18n.T("public.errorTitle"), "",
app.i18n.Ts2("public.invalidLink"))) app.i18n.Ts("public.invalidLink")))
} }
app.log.Printf("error fetching redirect link: %s", err) app.log.Printf("error fetching redirect link: %s", err)
return c.Render(http.StatusInternalServerError, tplMessage, return c.Render(http.StatusInternalServerError, tplMessage,
makeMsgTpl(app.i18n.T("public.errorTitle"), "", makeMsgTpl(app.i18n.T("public.errorTitle"), "",
app.i18n.Ts2("public.errorProcessingRequest"))) app.i18n.Ts("public.errorProcessingRequest")))
} }
return c.Redirect(http.StatusTemporaryRedirect, url) return c.Redirect(http.StatusTemporaryRedirect, url)
@ -368,7 +368,7 @@ func handleSelfExportSubscriberData(c echo.Context) error {
if !app.constants.Privacy.AllowExport { if !app.constants.Privacy.AllowExport {
return c.Render(http.StatusBadRequest, tplMessage, return c.Render(http.StatusBadRequest, tplMessage,
makeMsgTpl(app.i18n.T("public.errorTitle"), "", makeMsgTpl(app.i18n.T("public.errorTitle"), "",
app.i18n.Ts2("public.invalidFeature"))) app.i18n.Ts("public.invalidFeature")))
} }
// Get the subscriber's data. A single query that gets the profile, // Get the subscriber's data. A single query that gets the profile,
@ -379,7 +379,7 @@ func handleSelfExportSubscriberData(c echo.Context) error {
app.log.Printf("error exporting subscriber data: %s", err) app.log.Printf("error exporting subscriber data: %s", err)
return c.Render(http.StatusInternalServerError, tplMessage, return c.Render(http.StatusInternalServerError, tplMessage,
makeMsgTpl(app.i18n.T("public.errorTitle"), "", makeMsgTpl(app.i18n.T("public.errorTitle"), "",
app.i18n.Ts2("public.errorProcessingRequest"))) app.i18n.Ts("public.errorProcessingRequest")))
} }
// Prepare the attachment e-mail. // Prepare the attachment e-mail.
@ -388,7 +388,7 @@ func handleSelfExportSubscriberData(c echo.Context) error {
app.log.Printf("error compiling notification template '%s': %v", notifSubscriberData, err) app.log.Printf("error compiling notification template '%s': %v", notifSubscriberData, err)
return c.Render(http.StatusInternalServerError, tplMessage, return c.Render(http.StatusInternalServerError, tplMessage,
makeMsgTpl(app.i18n.T("public.errorTitle"), "", makeMsgTpl(app.i18n.T("public.errorTitle"), "",
app.i18n.Ts2("public.errorProcessingRequest"))) app.i18n.Ts("public.errorProcessingRequest")))
} }
// Send the data as a JSON attachment to the subscriber. // Send the data as a JSON attachment to the subscriber.
@ -409,7 +409,7 @@ func handleSelfExportSubscriberData(c echo.Context) error {
app.log.Printf("error e-mailing subscriber profile: %s", err) app.log.Printf("error e-mailing subscriber profile: %s", err)
return c.Render(http.StatusInternalServerError, tplMessage, return c.Render(http.StatusInternalServerError, tplMessage,
makeMsgTpl(app.i18n.T("public.errorTitle"), "", makeMsgTpl(app.i18n.T("public.errorTitle"), "",
app.i18n.Ts2("public.errorProcessingRequest"))) app.i18n.Ts("public.errorProcessingRequest")))
} }
return c.Render(http.StatusOK, tplMessage, return c.Render(http.StatusOK, tplMessage,
@ -430,14 +430,14 @@ func handleWipeSubscriberData(c echo.Context) error {
if !app.constants.Privacy.AllowWipe { if !app.constants.Privacy.AllowWipe {
return c.Render(http.StatusBadRequest, tplMessage, return c.Render(http.StatusBadRequest, tplMessage,
makeMsgTpl(app.i18n.T("public.errorTitle"), "", makeMsgTpl(app.i18n.T("public.errorTitle"), "",
app.i18n.Ts2("public.invalidFeature"))) app.i18n.Ts("public.invalidFeature")))
} }
if _, err := app.queries.DeleteSubscribers.Exec(nil, pq.StringArray{subUUID}); err != nil { if _, err := app.queries.DeleteSubscribers.Exec(nil, pq.StringArray{subUUID}); err != nil {
app.log.Printf("error wiping subscriber data: %s", err) app.log.Printf("error wiping subscriber data: %s", err)
return c.Render(http.StatusInternalServerError, tplMessage, return c.Render(http.StatusInternalServerError, tplMessage,
makeMsgTpl(app.i18n.T("public.errorTitle"), "", makeMsgTpl(app.i18n.T("public.errorTitle"), "",
app.i18n.Ts2("public.errorProcessingRequest"))) app.i18n.Ts("public.errorProcessingRequest")))
} }
return c.Render(http.StatusOK, tplMessage, return c.Render(http.StatusOK, tplMessage,

View File

@ -169,7 +169,7 @@ func handleUpdateSettings(c echo.Context) error {
name := reAlphaNum.ReplaceAllString(strings.ToLower(m.Name), "") name := reAlphaNum.ReplaceAllString(strings.ToLower(m.Name), "")
if _, ok := names[name]; ok { if _, ok := names[name]; ok {
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
app.i18n.Ts2("settings.duplicateMessengerName", "name", name)) app.i18n.Ts("settings.duplicateMessengerName", "name", name))
} }
if len(name) == 0 { if len(name) == 0 {
return echo.NewHTTPError(http.StatusBadRequest, app.i18n.T("settings.invalidMessengerName")) return echo.NewHTTPError(http.StatusBadRequest, app.i18n.T("settings.invalidMessengerName"))
@ -188,13 +188,13 @@ func handleUpdateSettings(c echo.Context) error {
b, err := json.Marshal(set) b, err := json.Marshal(set)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("settings.errorEncoding", "error", err.Error())) app.i18n.Ts("settings.errorEncoding", "error", err.Error()))
} }
// Update the settings in the DB. // Update the settings in the DB.
if _, err := app.queries.UpdateSettings.Exec(b); err != nil { if _, err := app.queries.UpdateSettings.Exec(b); err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorUpdating", app.i18n.Ts("globals.messages.errorUpdating",
"name", "{globals.terms.settings}", "error", pqErrMsg(err))) "name", "{globals.terms.settings}", "error", pqErrMsg(err)))
} }
@ -233,14 +233,14 @@ func getSettings(app *App) (settings, error) {
if err := app.queries.GetSettings.Get(&b); err != nil { if err := app.queries.GetSettings.Get(&b); err != nil {
return out, echo.NewHTTPError(http.StatusInternalServerError, return out, echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorFetching", app.i18n.Ts("globals.messages.errorFetching",
"name", "{globals.terms.settings}", "error", pqErrMsg(err))) "name", "{globals.terms.settings}", "error", pqErrMsg(err)))
} }
// Unmarshall the settings and filter out sensitive fields. // Unmarshall the settings and filter out sensitive fields.
if err := json.Unmarshal([]byte(b), &out); err != nil { if err := json.Unmarshal([]byte(b), &out); err != nil {
return out, echo.NewHTTPError(http.StatusInternalServerError, return out, echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("settings.errorEncoding", "error", err.Error())) app.i18n.Ts("settings.errorEncoding", "error", err.Error()))
} }
return out, nil return out, nil

View File

@ -128,14 +128,14 @@ func handleQuerySubscribers(c echo.Context) error {
if err != nil { if err != nil {
app.log.Printf("error preparing subscriber query: %v", err) app.log.Printf("error preparing subscriber query: %v", err)
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
app.i18n.Ts2("subscribers.errorPreparingQuery", "error", pqErrMsg(err))) app.i18n.Ts("subscribers.errorPreparingQuery", "error", pqErrMsg(err)))
} }
defer tx.Rollback() defer tx.Rollback()
// Run the query. stmt is the raw SQL query. // Run the query. stmt is the raw SQL query.
if err := tx.Select(&out.Results, stmt, listIDs, pg.Offset, pg.Limit); err != nil { if err := tx.Select(&out.Results, stmt, listIDs, pg.Offset, pg.Limit); err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorFetching", app.i18n.Ts("globals.messages.errorFetching",
"name", "{globals.terms.subscribers}", "error", pqErrMsg(err))) "name", "{globals.terms.subscribers}", "error", pqErrMsg(err)))
} }
@ -143,7 +143,7 @@ func handleQuerySubscribers(c echo.Context) error {
if err := out.Results.LoadLists(app.queries.GetSubscriberListsLazy); err != nil { if err := out.Results.LoadLists(app.queries.GetSubscriberListsLazy); err != nil {
app.log.Printf("error fetching subscriber lists: %v", err) app.log.Printf("error fetching subscriber lists: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorFetching", app.i18n.Ts("globals.messages.errorFetching",
"name", "{globals.terms.subscribers}", "error", pqErrMsg(err))) "name", "{globals.terms.subscribers}", "error", pqErrMsg(err)))
} }
@ -194,13 +194,13 @@ func handleExportSubscribers(c echo.Context) error {
if err != nil { if err != nil {
app.log.Printf("error preparing subscriber query: %v", err) app.log.Printf("error preparing subscriber query: %v", err)
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
app.i18n.Ts2("subscribers.errorPreparingQuery", "error", pqErrMsg(err))) app.i18n.Ts("subscribers.errorPreparingQuery", "error", pqErrMsg(err)))
} }
defer tx.Rollback() defer tx.Rollback()
if _, err := tx.Query(stmt, nil, 0, 1); err != nil { if _, err := tx.Query(stmt, nil, 0, 1); err != nil {
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
app.i18n.Ts2("subscribers.errorPreparingQuery", "error", pqErrMsg(err))) app.i18n.Ts("subscribers.errorPreparingQuery", "error", pqErrMsg(err)))
} }
} }
@ -208,7 +208,7 @@ func handleExportSubscribers(c echo.Context) error {
tx, err := db.Preparex(stmt) tx, err := db.Preparex(stmt)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
app.i18n.Ts2("subscribers.errorPreparingQuery", "error", pqErrMsg(err))) app.i18n.Ts("subscribers.errorPreparingQuery", "error", pqErrMsg(err)))
} }
// Run the query until all rows are exhausted. // Run the query until all rows are exhausted.
@ -231,7 +231,7 @@ loop:
var out []models.SubscriberExport var out []models.SubscriberExport
if err := tx.Select(&out, listIDs, id, app.constants.DBBatchSize); err != nil { if err := tx.Select(&out, listIDs, id, app.constants.DBBatchSize); err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorFetching", app.i18n.Ts("globals.messages.errorFetching",
"name", "{globals.terms.subscribers}", "error", pqErrMsg(err))) "name", "{globals.terms.subscribers}", "error", pqErrMsg(err)))
} }
if len(out) == 0 { if len(out) == 0 {
@ -309,7 +309,7 @@ func handleUpdateSubscriber(c echo.Context) error {
if err != nil { if err != nil {
app.log.Printf("error updating subscriber: %v", err) app.log.Printf("error updating subscriber: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorUpdating", app.i18n.Ts("globals.messages.errorUpdating",
"name", "{globals.terms.subscriber}", "error", pqErrMsg(err))) "name", "{globals.terms.subscriber}", "error", pqErrMsg(err)))
} }
@ -340,12 +340,12 @@ func handleSubscriberSendOptin(c echo.Context) error {
if err != nil { if err != nil {
app.log.Printf("error fetching subscriber: %v", err) app.log.Printf("error fetching subscriber: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorFetching", app.i18n.Ts("globals.messages.errorFetching",
"name", "{globals.terms.subscribers}", "error", pqErrMsg(err))) "name", "{globals.terms.subscribers}", "error", pqErrMsg(err)))
} }
if len(out) == 0 { if len(out) == 0 {
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
app.i18n.Ts2("globals.messages.notFound", "name", "{globals.terms.subscriber}")) app.i18n.Ts("globals.messages.notFound", "name", "{globals.terms.subscriber}"))
} }
if err := sendOptinConfirmation(out[0], nil, app); err != nil { if err := sendOptinConfirmation(out[0], nil, app); err != nil {
@ -377,7 +377,7 @@ func handleBlocklistSubscribers(c echo.Context) error {
var req subQueryReq var req subQueryReq
if err := c.Bind(&req); err != nil { if err := c.Bind(&req); err != nil {
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
app.i18n.Ts2("subscribers.errorInvalidIDs", "error", err.Error())) app.i18n.Ts("subscribers.errorInvalidIDs", "error", err.Error()))
} }
if len(req.SubscriberIDs) == 0 { if len(req.SubscriberIDs) == 0 {
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
@ -389,7 +389,7 @@ func handleBlocklistSubscribers(c echo.Context) error {
if _, err := app.queries.BlocklistSubscribers.Exec(IDs); err != nil { if _, err := app.queries.BlocklistSubscribers.Exec(IDs); err != nil {
app.log.Printf("error blocklisting subscribers: %v", err) app.log.Printf("error blocklisting subscribers: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("subscribers.errorBlocklisting", "error", err.Error())) app.i18n.Ts("subscribers.errorBlocklisting", "error", err.Error()))
} }
return c.JSON(http.StatusOK, okResp{true}) return c.JSON(http.StatusOK, okResp{true})
@ -417,7 +417,7 @@ func handleManageSubscriberLists(c echo.Context) error {
var req subQueryReq var req subQueryReq
if err := c.Bind(&req); err != nil { if err := c.Bind(&req); err != nil {
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
app.i18n.Ts2("subscribers.errorInvalidIDs", "error", err.Error())) app.i18n.Ts("subscribers.errorInvalidIDs", "error", err.Error()))
} }
if len(req.SubscriberIDs) == 0 { if len(req.SubscriberIDs) == 0 {
return echo.NewHTTPError(http.StatusBadRequest, app.i18n.T("subscribers.errorNoIDs")) return echo.NewHTTPError(http.StatusBadRequest, app.i18n.T("subscribers.errorNoIDs"))
@ -445,7 +445,7 @@ func handleManageSubscriberLists(c echo.Context) error {
if err != nil { if err != nil {
app.log.Printf("error updating subscriptions: %v", err) app.log.Printf("error updating subscriptions: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorUpdating", app.i18n.Ts("globals.messages.errorUpdating",
"name", "{globals.terms.subscribers}", "error", err.Error())) "name", "{globals.terms.subscribers}", "error", err.Error()))
} }
@ -473,11 +473,11 @@ func handleDeleteSubscribers(c echo.Context) error {
i, err := parseStringIDs(c.Request().URL.Query()["id"]) i, err := parseStringIDs(c.Request().URL.Query()["id"])
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
app.i18n.Ts2("subscribers.errorInvalidIDs", "error", err.Error())) app.i18n.Ts("subscribers.errorInvalidIDs", "error", err.Error()))
} }
if len(i) == 0 { if len(i) == 0 {
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
app.i18n.Ts2("subscribers.errorNoIDs", "error", err.Error())) app.i18n.Ts("subscribers.errorNoIDs", "error", err.Error()))
} }
IDs = i IDs = i
} }
@ -485,7 +485,7 @@ func handleDeleteSubscribers(c echo.Context) error {
if _, err := app.queries.DeleteSubscribers.Exec(IDs, nil); err != nil { if _, err := app.queries.DeleteSubscribers.Exec(IDs, nil); err != nil {
app.log.Printf("error deleting subscribers: %v", err) app.log.Printf("error deleting subscribers: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorDeleting", app.i18n.Ts("globals.messages.errorDeleting",
"name", "{globals.terms.subscribers}", "error", pqErrMsg(err))) "name", "{globals.terms.subscribers}", "error", pqErrMsg(err)))
} }
@ -510,7 +510,7 @@ func handleDeleteSubscribersByQuery(c echo.Context) error {
if err != nil { if err != nil {
app.log.Printf("error deleting subscribers: %v", err) app.log.Printf("error deleting subscribers: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorDeleting", app.i18n.Ts("globals.messages.errorDeleting",
"name", "{globals.terms.subscribers}", "error", pqErrMsg(err))) "name", "{globals.terms.subscribers}", "error", pqErrMsg(err)))
} }
@ -535,7 +535,7 @@ func handleBlocklistSubscribersByQuery(c echo.Context) error {
if err != nil { if err != nil {
app.log.Printf("error blocklisting subscribers: %v", err) app.log.Printf("error blocklisting subscribers: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("subscribers.errorBlocklisting", "error", pqErrMsg(err))) app.i18n.Ts("subscribers.errorBlocklisting", "error", pqErrMsg(err)))
} }
return c.JSON(http.StatusOK, okResp{true}) return c.JSON(http.StatusOK, okResp{true})
@ -575,7 +575,7 @@ func handleManageSubscriberListsByQuery(c echo.Context) error {
if err != nil { if err != nil {
app.log.Printf("error updating subscriptions: %v", err) app.log.Printf("error updating subscriptions: %v", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorUpdating", app.i18n.Ts("globals.messages.errorUpdating",
"name", "{globals.terms.subscribers}", "error", pqErrMsg(err))) "name", "{globals.terms.subscribers}", "error", pqErrMsg(err)))
} }
@ -603,7 +603,7 @@ func handleExportSubscriberData(c echo.Context) error {
if err != nil { if err != nil {
app.log.Printf("error exporting subscriber data: %s", err) app.log.Printf("error exporting subscriber data: %s", err)
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorFetching", app.i18n.Ts("globals.messages.errorFetching",
"name", "{globals.terms.subscribers}", "error", err.Error())) "name", "{globals.terms.subscribers}", "error", err.Error()))
} }
@ -636,7 +636,7 @@ func insertSubscriber(req subimporter.SubReq, app *App) (models.Subscriber, erro
app.log.Printf("error inserting subscriber: %v", err) app.log.Printf("error inserting subscriber: %v", err)
return req.Subscriber, echo.NewHTTPError(http.StatusInternalServerError, return req.Subscriber, echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorCreating", app.i18n.Ts("globals.messages.errorCreating",
"name", "{globals.terms.subscriber}", "error", pqErrMsg(err))) "name", "{globals.terms.subscriber}", "error", pqErrMsg(err)))
} }
@ -665,17 +665,17 @@ func getSubscriber(id int, app *App) (models.Subscriber, error) {
if err := app.queries.GetSubscriber.Select(&out, id, nil); err != nil { if err := app.queries.GetSubscriber.Select(&out, id, nil); err != nil {
app.log.Printf("error fetching subscriber: %v", err) app.log.Printf("error fetching subscriber: %v", err)
return models.Subscriber{}, echo.NewHTTPError(http.StatusInternalServerError, return models.Subscriber{}, echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorFetching", app.i18n.Ts("globals.messages.errorFetching",
"name", "{globals.terms.subscriber}", "error", pqErrMsg(err))) "name", "{globals.terms.subscriber}", "error", pqErrMsg(err)))
} }
if len(out) == 0 { if len(out) == 0 {
return models.Subscriber{}, echo.NewHTTPError(http.StatusBadRequest, return models.Subscriber{}, echo.NewHTTPError(http.StatusBadRequest,
app.i18n.Ts2("globals.messages.notFound", "name", "{globals.terms.subscriber}")) app.i18n.Ts("globals.messages.notFound", "name", "{globals.terms.subscriber}"))
} }
if err := out.LoadLists(app.queries.GetSubscriberListsLazy); err != nil { if err := out.LoadLists(app.queries.GetSubscriberListsLazy); err != nil {
app.log.Printf("error loading subscriber lists: %v", err) app.log.Printf("error loading subscriber lists: %v", err)
return models.Subscriber{}, echo.NewHTTPError(http.StatusInternalServerError, return models.Subscriber{}, echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorFetching", app.i18n.Ts("globals.messages.errorFetching",
"name", "{globals.terms.lists}", "error", pqErrMsg(err))) "name", "{globals.terms.lists}", "error", pqErrMsg(err)))
} }

View File

@ -50,12 +50,12 @@ func handleGetTemplates(c echo.Context) error {
err := app.queries.GetTemplates.Select(&out, id, noBody) err := app.queries.GetTemplates.Select(&out, id, noBody)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorFetching", app.i18n.Ts("globals.messages.errorFetching",
"name", "{globals.terms.templates}", "error", pqErrMsg(err))) "name", "{globals.terms.templates}", "error", pqErrMsg(err)))
} }
if single && len(out) == 0 { if single && len(out) == 0 {
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
app.i18n.Ts2("globals.messages.notFound", "name", "{globals.terms.template}")) app.i18n.Ts("globals.messages.notFound", "name", "{globals.terms.template}"))
} }
if len(out) == 0 { if len(out) == 0 {
@ -80,7 +80,7 @@ func handlePreviewTemplate(c echo.Context) error {
if body != "" { if body != "" {
if !regexpTplTag.MatchString(body) { if !regexpTplTag.MatchString(body) {
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
app.i18n.Ts2("templates.placeholderHelp", "placeholder", tplTag)) app.i18n.Ts("templates.placeholderHelp", "placeholder", tplTag))
} }
} else { } else {
if id < 1 { if id < 1 {
@ -90,13 +90,13 @@ func handlePreviewTemplate(c echo.Context) error {
err := app.queries.GetTemplates.Select(&tpls, id, false) err := app.queries.GetTemplates.Select(&tpls, id, false)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorFetching", app.i18n.Ts("globals.messages.errorFetching",
"name", "{globals.terms.templates}", "error", pqErrMsg(err))) "name", "{globals.terms.templates}", "error", pqErrMsg(err)))
} }
if len(tpls) == 0 { if len(tpls) == 0 {
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
app.i18n.Ts2("globals.messages.notFound", "name", "{globals.terms.template}")) app.i18n.Ts("globals.messages.notFound", "name", "{globals.terms.template}"))
} }
body = tpls[0].Body body = tpls[0].Body
} }
@ -113,14 +113,14 @@ func handlePreviewTemplate(c echo.Context) error {
if err := camp.CompileTemplate(app.manager.TemplateFuncs(&camp)); err != nil { if err := camp.CompileTemplate(app.manager.TemplateFuncs(&camp)); err != nil {
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
app.i18n.Ts2("templates.errorCompiling", "error", err.Error())) app.i18n.Ts("templates.errorCompiling", "error", err.Error()))
} }
// Render the message body. // Render the message body.
m := app.manager.NewCampaignMessage(&camp, dummySubscriber) m := app.manager.NewCampaignMessage(&camp, dummySubscriber)
if err := m.Render(); err != nil { if err := m.Render(); err != nil {
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
app.i18n.Ts2("templates.errorRendering", "error", err.Error())) app.i18n.Ts("templates.errorRendering", "error", err.Error()))
} }
return c.HTML(http.StatusOK, string(m.Body())) return c.HTML(http.StatusOK, string(m.Body()))
@ -147,7 +147,7 @@ func handleCreateTemplate(c echo.Context) error {
o.Name, o.Name,
o.Body); err != nil { o.Body); err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorCreating", app.i18n.Ts("globals.messages.errorCreating",
"name", "{globals.terms.template}", "error", pqErrMsg(err))) "name", "{globals.terms.template}", "error", pqErrMsg(err)))
} }
@ -181,13 +181,13 @@ func handleUpdateTemplate(c echo.Context) error {
res, err := app.queries.UpdateTemplate.Exec(o.ID, o.Name, o.Body) res, err := app.queries.UpdateTemplate.Exec(o.ID, o.Name, o.Body)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorUpdating", app.i18n.Ts("globals.messages.errorUpdating",
"name", "{globals.terms.template}", "error", pqErrMsg(err))) "name", "{globals.terms.template}", "error", pqErrMsg(err)))
} }
if n, _ := res.RowsAffected(); n == 0 { if n, _ := res.RowsAffected(); n == 0 {
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
app.i18n.Ts2("globals.messages.notFound", "name", "{globals.terms.template}")) app.i18n.Ts("globals.messages.notFound", "name", "{globals.terms.template}"))
} }
return handleGetTemplates(c) return handleGetTemplates(c)
@ -207,7 +207,7 @@ func handleTemplateSetDefault(c echo.Context) error {
_, err := app.queries.SetDefaultTemplate.Exec(id) _, err := app.queries.SetDefaultTemplate.Exec(id)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorUpdating", app.i18n.Ts("globals.messages.errorUpdating",
"name", "{globals.terms.template}", "error", pqErrMsg(err))) "name", "{globals.terms.template}", "error", pqErrMsg(err)))
} }
@ -236,7 +236,7 @@ func handleDeleteTemplate(c echo.Context) error {
} }
return echo.NewHTTPError(http.StatusInternalServerError, return echo.NewHTTPError(http.StatusInternalServerError,
app.i18n.Ts2("globals.messages.errorCreating", app.i18n.Ts("globals.messages.errorCreating",
"name", "{globals.terms.template}", "error", pqErrMsg(err))) "name", "{globals.terms.template}", "error", pqErrMsg(err)))
} }
@ -256,7 +256,7 @@ func validateTemplate(o models.Template, app *App) error {
if !regexpTplTag.MatchString(o.Body) { if !regexpTplTag.MatchString(o.Body) {
return echo.NewHTTPError(http.StatusBadRequest, return echo.NewHTTPError(http.StatusBadRequest,
app.i18n.Ts2("templates.placeholderHelp", "placeholder", tplTag)) app.i18n.Ts("templates.placeholderHelp", "placeholder", tplTag))
} }
return nil return nil

View File

@ -43,7 +43,7 @@
<form @submit.prevent="onSubmit"> <form @submit.prevent="onSubmit">
<b-field :label="$t('globals.fields.name')" label-position="on-border"> <b-field :label="$t('globals.fields.name')" label-position="on-border">
<b-input :maxlength="200" :ref="'focus'" v-model="form.name" :disabled="!canEdit" <b-input :maxlength="200" :ref="'focus'" v-model="form.name" :disabled="!canEdit"
placeholder="$t('globals.fields.name')" required></b-input> :placeholder="$t('globals.fields.name')" required></b-input>
</b-field> </b-field>
<b-field :label="$t('campaigns.subject')" label-position="on-border"> <b-field :label="$t('campaigns.subject')" label-position="on-border">

View File

@ -54,33 +54,12 @@ func (i *I18nLang) T(key string) string {
// Ts returns the translation for the given key similar to vue i18n's t() // Ts returns the translation for the given key similar to vue i18n's t()
// and subsitutes the params in the given map in the translated value. // and subsitutes the params in the given map in the translated value.
// In the language values, the substitutions are represented as: {key} // In the language values, the substitutions are represented as: {key}
func (i *I18nLang) Ts(key string, params map[string]string) string {
s, ok := i.langMap[key]
if !ok {
return key
}
s = i.getSingular(s)
for p, val := range params {
// If there are {params} in the map values, substitute them.
val = i.subAllParams(val)
s = strings.ReplaceAll(s, `{`+p+`}`, val)
}
return s
}
// Ts2 returns the translation for the given key similar to vue i18n's t()
// and subsitutes the params in the given map in the translated value.
// In the language values, the substitutions are represented as: {key}
// The params and values are received as a pairs of succeeding strings. // The params and values are received as a pairs of succeeding strings.
// That is, the number of these arguments should be an even number. // That is, the number of these arguments should be an even number.
// eg: Ts2("globals.message.notFound", // eg: Ts("globals.message.notFound",
// "name", "campaigns", // "name", "campaigns",
// "error", err) // "error", err)
func (i *I18nLang) Ts2(key string, params ...string) string { func (i *I18nLang) Ts(key string, params ...string) string {
if len(params)%2 != 0 { if len(params)%2 != 0 {
return key + `: Invalid arguments` return key + `: Invalid arguments`
} }