package main import ( "bytes" "database/sql" "encoding/gob" "fmt" "html" "net/http" "net/mail" "os" "path/filepath" "strings" ) var ch = make(chan []byte) func Web(db *sql.DB) { go func() { err := http.ListenAndServe("127.0.1.69:3141", http.HandlerFunc(Http)) if err != nil { ch <- []byte("EXIT") } }() var b []byte var r *sql.Rows var m []EmailMeta var bb bytes.Buffer for { b = <-ch if string(b) == "EXIT" { break } r, _ = db.Query(string(b)) m, _ = ReadRows(r) gob.NewEncoder(&bb).Encode(m) ch <- bb.Bytes() bb.Reset() r.Close() } } func E(s ...string) []any { a := make([]any, len(s)) for i, v := range s { a[i] = html.EscapeString(v) } return a } func Http(w http.ResponseWriter, r *http.Request) { if r.URL.Path == "/" { r.ParseForm() var q []string if r.Form.Get("to") != "" { q = append(q, fmt.Sprintf(` toaddr LIKE '%%%s%%'`, r.Form.Get("to"))) } if r.Form.Get("from") != "" { q = append(q, fmt.Sprintf(` fromaddr LIKE '%%%s%%'`, r.Form.Get("from"))) } if r.Form.Get("subject") != "" { q = append(q, fmt.Sprintf(` subject LIKE '%%%s%%'`, r.Form.Get("subject"))) } if r.Form.Get("date") != "" { q = append(q, fmt.Sprintf(` date LIKE '%%%s%%'`, r.Form.Get("date"))) } ch <- []byte(fmt.Sprintf("SELECT * FROM emails %s ORDER BY date DESC", func() string { if len(q) == 0 { return "" } return "WHERE " + strings.Join(q, " AND ") }())) var metas []EmailMeta var b []byte b = <-ch dec := gob.NewDecoder(strings.NewReader(string(b))) if dec.Decode(&metas) != nil { http.Error(w, "Internal Server Error", 500) return } fmt.Fprint(w, `Emails `) var from *mail.Address for _, em := range metas { from, _ = mail.ParseAddress(em.From) if from.Name == "" { if strings.Contains(from.Address, "@") { from.Name = strings.Split(from.Address, "@")[0] } else { from.Name = from.Address } } fmt.Fprintf(w, `
%s
%s
%s
%s
`, E(em.Id, TimeStr(em.Date), from.Address, from.Name, em.To, func() string { a, err := mail.ParseAddressList(em.To) if err != nil { return em.To } return strings.Split(a[0].Address+"@", "@")[0] }(), em.Subject)...) } fmt.Fprintf(w, "") return } if filepath.Base(r.URL.Path) == "html.html" && len(strings.Split(r.URL.Path[1:], "/")) == 2 { id := filepath.Base(filepath.Dir(r.URL.Path)) s, _ := os.ReadFile(filepath.Join(SAVEPATH, id, "header.txt")) b, _ := os.ReadFile(filepath.Join(SAVEPATH, id, "body.txt")) fmt.Fprintf(w, `%s
%s

%s
`, id, string(s), string(b), "/"+id) return } http.FileServer(http.Dir(SAVEPATH)).ServeHTTP(w, r) }