diff --git a/config.go b/config/config.go similarity index 99% rename from config.go rename to config/config.go index c2aa58a..65f56a3 100644 --- a/config.go +++ b/config/config.go @@ -1,4 +1,4 @@ -package inbucket +package config import ( "container/list" diff --git a/main/inbucketd.go b/main/inbucketd.go index e44d165..6c980af 100644 --- a/main/inbucketd.go +++ b/main/inbucketd.go @@ -6,7 +6,7 @@ package main import ( "flag" "fmt" - "github.com/jhillyerd/inbucket" + "github.com/jhillyerd/inbucket/config" "github.com/jhillyerd/inbucket/smtpd" "github.com/jhillyerd/inbucket/web" "os" @@ -26,7 +26,7 @@ func main() { flag.Usage() os.Exit(1) } - err := inbucket.LoadConfig(flag.Arg(0)) + err := config.LoadConfig(flag.Arg(0)) if err != nil { fmt.Fprintf(os.Stderr, "Failed to parse config: %v\n", err) os.Exit(1) diff --git a/smtpd/datastore.go b/smtpd/datastore.go index 67a8d65..e623174 100644 --- a/smtpd/datastore.go +++ b/smtpd/datastore.go @@ -5,7 +5,7 @@ import ( "encoding/gob" "errors" "fmt" - "github.com/jhillyerd/inbucket" + "github.com/jhillyerd/inbucket/config" "github.com/jhillyerd/inbucket/log" "io/ioutil" "net/mail" @@ -42,7 +42,7 @@ type DataStore struct { // NewDataStore creates a new DataStore object. It uses the inbucket.Config object to // construct it's path. func NewDataStore() *DataStore { - path, err := inbucket.Config.String("datastore", "path") + path, err := config.Config.String("datastore", "path") if err != nil { log.Error("Error getting datastore path: %v", err) return nil diff --git a/smtpd/listener.go b/smtpd/listener.go index d442c0a..00e1afc 100644 --- a/smtpd/listener.go +++ b/smtpd/listener.go @@ -2,7 +2,7 @@ package smtpd import ( "fmt" - "github.com/jhillyerd/inbucket" + "github.com/jhillyerd/inbucket/config" "github.com/jhillyerd/inbucket/log" "net" ) @@ -20,13 +20,13 @@ type Server struct { func New() *Server { ds := NewDataStore() // TODO Make more of these configurable - return &Server{domain: inbucket.GetSmtpConfig().Domain, maxRecips: 100, maxIdleSeconds: 300, + return &Server{domain: config.GetSmtpConfig().Domain, maxRecips: 100, maxIdleSeconds: 300, dataStore: ds, maxMessageBytes: 2048000} } // Main listener loop func (s *Server) Start() { - cfg := inbucket.GetSmtpConfig() + cfg := config.GetSmtpConfig() addr, err := net.ResolveTCPAddr("tcp4", fmt.Sprintf("%v:%v", cfg.Ip4address, cfg.Ip4port)) if err != nil { diff --git a/smtpd/utils.go b/smtpd/utils.go index fa2c0ff..1bef50d 100644 --- a/smtpd/utils.go +++ b/smtpd/utils.go @@ -3,7 +3,6 @@ package smtpd import ( "crypto/sha1" "fmt" - "html" "io" "strings" ) @@ -26,11 +25,3 @@ func HashMailboxName(mailbox string) string { io.WriteString(h, mailbox) return fmt.Sprintf("%x", h.Sum(nil)) } - -// TextToHtml takes plain text, escapes it and tries to pretty it up for -// HTML display -func TextToHtml(text string) string { - text = html.EscapeString(text) - replacer := strings.NewReplacer("\r\n", "
\n", "\r", "
\n", "\n", "
\n") - return replacer.Replace(text) -} diff --git a/smtpd/utils_test.go b/smtpd/utils_test.go index 1643679..4ea774e 100644 --- a/smtpd/utils_test.go +++ b/smtpd/utils_test.go @@ -6,38 +6,11 @@ import ( ) func TestParseMailboxName(t *testing.T) { - in, out := "MailBOX", "mailbox" - if x := ParseMailboxName(in); x != out { - t.Errorf("ParseMailboxName(%v) = %v, want %v", in, x, out) - } - - in, out = "MailBox@Host.Com", "mailbox" - if x := ParseMailboxName(in); x != out { - t.Errorf("ParseMailboxName(%v) = %v, want %v", in, x, out) - } - - in, out = "Mail+extra@Host.Com", "mail" - if x := ParseMailboxName(in); x != out { - t.Errorf("ParseMailboxName(%v) = %v, want %v", in, x, out) - } + assert.Equal(t, ParseMailboxName("MailBOX"), "mailbox") + assert.Equal(t, ParseMailboxName("MailBox@Host.Com"), "mailbox") + assert.Equal(t, ParseMailboxName("Mail+extra@Host.Com"), "mail") } func TestHashMailboxName(t *testing.T) { - in, out := "mail", "1d6e1cf70ec6f9ab28d3ea4b27a49a77654d370e" - if x := HashMailboxName(in); x != out { - t.Errorf("HashMailboxName(%v) = %v, want %v", in, x, out) - } -} - -func TestTextToHtml(t *testing.T) { - // Identity - assert.Equal(t, TextToHtml("html"), "html") - - // Check it escapes - assert.Equal(t, TextToHtml(""), "<html>") - - // Check for linebreaks - assert.Equal(t, TextToHtml("line\nbreak"), "line
\nbreak") - assert.Equal(t, TextToHtml("line\r\nbreak"), "line
\nbreak") - assert.Equal(t, TextToHtml("line\rbreak"), "line
\nbreak") + assert.Equal(t, HashMailboxName("mail"), "1d6e1cf70ec6f9ab28d3ea4b27a49a77654d370e") } diff --git a/web/helpers.go b/web/helpers.go index 0315c00..4e7d48e 100644 --- a/web/helpers.go +++ b/web/helpers.go @@ -3,24 +3,29 @@ package web import ( "fmt" "github.com/jhillyerd/inbucket/log" + "html" "html/template" + "strings" "time" ) var TemplateFuncs = template.FuncMap{ - // Reversable routing function (shared with templates) + "friendlyTime": friendlyTime, "reverse": reverse, - // Friendly date & time rendering - "friendlyTime": func(t time.Time) template.HTML { - ty, tm, td := t.Date() - ny, nm, nd := time.Now().Date() - if (ty == ny) && (tm == nm) && (td == nd) { - return template.HTML(t.Format("03:04:05 PM")) - } - return template.HTML(t.Format("Mon Jan 2, 2006")) - }, + "textToHtml": textToHtml, } +// Friendly date & time rendering +func friendlyTime(t time.Time) template.HTML { + ty, tm, td := t.Date() + ny, nm, nd := time.Now().Date() + if (ty == ny) && (tm == nm) && (td == nd) { + return template.HTML(t.Format("03:04:05 PM")) + } + return template.HTML(t.Format("Mon Jan 2, 2006")) +} + +// Reversable routing function (shared with templates) func reverse(name string, things ...interface{}) string { // Convert the things to strings strs := make([]string, len(things)) @@ -35,3 +40,11 @@ func reverse(name string, things ...interface{}) string { } return u.Path } + +// textToHtml takes plain text, escapes it and tries to pretty it up for +// HTML display +func textToHtml(text string) template.HTML { + text = html.EscapeString(text) + replacer := strings.NewReplacer("\r\n", "
\n", "\r", "
\n", "\n", "
\n") + return template.HTML(replacer.Replace(text)) +} diff --git a/web/helpers_test.go b/web/helpers_test.go new file mode 100644 index 0000000..44936b0 --- /dev/null +++ b/web/helpers_test.go @@ -0,0 +1,19 @@ +package web + +import ( + "github.com/stretchrcom/testify/assert" + "testing" +) + +func TestTextToHtml(t *testing.T) { + // Identity + assert.Equal(t, textToHtml("html"), "html") + + // Check it escapes + assert.Equal(t, textToHtml(""), "<html>") + + // Check for linebreaks + assert.Equal(t, textToHtml("line\nbreak"), "line
\nbreak") + assert.Equal(t, textToHtml("line\r\nbreak"), "line
\nbreak") + assert.Equal(t, textToHtml("line\rbreak"), "line
\nbreak") +} diff --git a/web/mailbox_controller.go b/web/mailbox_controller.go index da80ddb..06edf8e 100644 --- a/web/mailbox_controller.go +++ b/web/mailbox_controller.go @@ -1,7 +1,6 @@ package web import ( - "github.com/jhillyerd/inbucket" "github.com/jhillyerd/inbucket/log" "html/template" "io" @@ -73,7 +72,7 @@ func MailboxShow(w http.ResponseWriter, req *http.Request, ctx *Context) (err er if err != nil { return err } - body := template.HTML(inbucket.TextToHtml(mime.Text)) + body := template.HTML(textToHtml(mime.Text)) htmlAvailable := mime.Html != "" return RenderPartial("mailbox/_show.html", w, map[string]interface{}{ diff --git a/web/server.go b/web/server.go index b36c6c7..c0d7a52 100644 --- a/web/server.go +++ b/web/server.go @@ -7,7 +7,7 @@ import ( "fmt" "github.com/gorilla/mux" "github.com/gorilla/sessions" - "github.com/jhillyerd/inbucket" + "github.com/jhillyerd/inbucket/config" "github.com/jhillyerd/inbucket/log" "net/http" "thegoods.biz/httpbuf" @@ -20,7 +20,7 @@ var Router *mux.Router var sessionStore sessions.Store -func setupRoutes(cfg inbucket.WebConfig) { +func setupRoutes(cfg config.WebConfig) { Router = mux.NewRouter() log.Info("Theme templates mapped to '%v'", cfg.TemplateDir) log.Info("Theme static content mapped to '%v'", cfg.PublicDir) @@ -42,7 +42,7 @@ func setupRoutes(cfg inbucket.WebConfig) { // Start() the web server func Start() { - cfg := inbucket.GetWebConfig() + cfg := config.GetWebConfig() setupRoutes(cfg) sessionStore = sessions.NewCookieStore([]byte("something-very-secret")) diff --git a/web/template.go b/web/template.go index df687c1..aff5744 100644 --- a/web/template.go +++ b/web/template.go @@ -1,7 +1,7 @@ package web import ( - "github.com/jhillyerd/inbucket" + "github.com/jhillyerd/inbucket/config" "github.com/jhillyerd/inbucket/log" "html/template" "net/http" @@ -49,7 +49,7 @@ func ParseTemplate(name string, partial bool) (*template.Template, error) { return t, nil } - cfg := inbucket.GetWebConfig() + cfg := config.GetWebConfig() tempPath := strings.Replace(name, "/", string(filepath.Separator), -1) tempFile := filepath.Join(cfg.TemplateDir, tempPath) log.Trace("Parsing template %v", tempFile)