uwu uwu poo poo
sophuwu sophie@skisiel.com
Sat, 20 Jul 2024 07:55:21 +0200
A
cli.go
@@ -0,0 +1,43 @@
+package main + +import ( + "bytes" + "fmt" + "github.com/andybalholm/brotli" + "strings" + "time" +) + +func TimeStr(s int64) string { + t := time.Unix(s, 0).Local() + n := time.Now().Local() + return strings.ReplaceAll(func() string { + if t.Year() != n.Year() { + return t.Format("Jan 02th 2006") + } + d := time.Since(t) + if d.Hours() > 24*6 { + return t.Format("Jan 02th") + } + if d.Hours() > 24 { + return t.Format("Monday 15:04") + } + if d.Hours() > 1 { + return fmt.Sprintf("%d hours ago", int(d.Hours())) + } + return fmt.Sprintf("%d minutes ago", int(d.Minutes())) + }(), "th", (func() string { + if t.Day()%9 < 1 || t.Day()%9 > 3 { + return "th" + } + return []string{"st", "nd", "rd"}[t.Day()%9-1] + })()) +} + +func UnBr(buf *bytes.Buffer) error { + data := buf.Bytes() + buf.Reset() + reader := brotli.NewReader(bytes.NewReader(data)) + _, err := buf.ReadFrom(reader) + return err +}
M
main.go
→
main.go
@@ -1,90 +1,17 @@
package main import ( - "bytes" - "crypto/sha1" - "encoding/json" - "fmt" - "github.com/DusanKasan/parsemail" - "github.com/andybalholm/brotli" "os" - "time" + "path/filepath" ) -func br(buf *bytes.Buffer) error { - data := buf.Bytes() - buf.Reset() - // Create a new buffer to hold the compressed data - writer := brotli.NewWriter(buf) - _, err := writer.Write(data) - if err != nil { - return err - } - // Close the writer to flush any remaining data - return writer.Close() -} - func main() { - // if len(os.Args)>0 && filepath.Base(os.Args[0])== "mailbox-parse"{ - var email bytes.Buffer - if _, err := email.ReadFrom(os.Stdin); err != nil { - os.Exit(1) + if len(os.Args) > 0 && filepath.Base(os.Args[0]) == "mailbox-parser" { + Parse() + return } - meta, err := GenerateMeta(email) - if err != nil { - os.Exit(1) + if len(os.Args) > 1 && os.Args[1] == "parse" { + Parse() + return } - js, _ := json.Marshal(meta) - fmt.Println(string(js)) - _ = br(&email) - - // } -} - -// GenerateMeta generates the EmailMeta for the EmailData -// This is used to index the email in the database -func GenerateMeta(email bytes.Buffer) (EmailMeta, error) { - var em EmailMeta - em.Id = fmt.Sprintf("%X", sha1.Sum(email.Bytes())) - - e, err := parsemail.Parse(&email) - - if err != nil { - return em, err - } - if e.Header["X-Original-To"] != nil { - em.To = e.Header["X-Original-To"][0] - } else if len(e.To) > 0 { - em.To = e.To[0].String() - } else { - em.To = "Unknown" - } - if len(e.From) > 0 { - em.From = e.From[0].String() - } else if e.Header["Return-Path"] != nil { - em.From = e.Header["Return-Path"][0] - } else { - em.From = "Unknown" - } - if len(e.Subject) > 0 { - em.Subject = e.Subject - } else { - em.Subject = "No Subject" - } - if !e.Date.IsZero() { - em.Date = e.Date.Local().Unix() - } else { - em.Date = time.Now().Local().Unix() - } - - return em, nil -} - -// EmailMeta contains the fields that will be searchable in the database -type EmailMeta struct { - From string `storm:"index" json:"from"` - To string `storm:"index" json:"to"` - Subject string `storm:"index" json:"subject"` - Date int64 `storm:"index" json:"date"` - Id string `storm:"id" json:"id"` }
A
parse.go
@@ -0,0 +1,90 @@
+package main + +import ( + "bytes" + "crypto/sha1" + "fmt" + "github.com/andybalholm/brotli" + "net/mail" + "os" + "time" +) + +func Br(buf *bytes.Buffer) error { + data := buf.Bytes() + buf.Reset() + writer := brotli.NewWriter(buf) + _, err := writer.Write(data) + if err != nil { + return err + } + return writer.Close() +} + +func Parse() { + var email bytes.Buffer + if _, err := email.ReadFrom(os.Stdin); err != nil { + os.Exit(1) + } + meta, err := GenerateMeta(email) + if err != nil { + os.Exit(1) + } + _ = meta + if Br(&email) != nil { + os.Exit(1) + } + fmt.Printf("%v\n", meta) +} + +// firstHeader returns the first email address in the list of headers +func firstHeader(e *mail.Header, s ...string) string { + var addr []*mail.Address + var err error + for _, v := range s { + if addr, err = e.AddressList(v); err == nil && len(addr) > 0 { + return addr[0].String() + } + } + return "Unknown" +} + +func dateHeader(e *mail.Header) int64 { + var d time.Time + var err error + d, err = e.Date() + if err != nil { + d = time.Now().Local() + } + return d.UTC().Unix() +} + +// GenerateMeta generates the EmailMeta for the EmailData +// This is used to index the email in the database +func GenerateMeta(email bytes.Buffer) (EmailMeta, error) { + var em EmailMeta + em.Id = fmt.Sprintf("%X", sha1.Sum(email.Bytes())) + em.Subject = "No Subject" + + // e, err := parsemail.Parse(&email) + e, err := mail.ReadMessage(&email) + if err != nil { + return em, err + } + em.To = firstHeader(&e.Header, "To", "X-Original-To", "Delivered-To") + em.From = firstHeader(&e.Header, "From", "Reply-To", "Return-Path", "Sender") + if s := e.Header.Get("Subject"); s != "" { + em.Subject = s + } + em.Date = dateHeader(&e.Header) + return em, nil +} + +// EmailMeta contains the fields that will be searchable in the database +type EmailMeta struct { + From string `storm:"index" json:"from"` + To string `storm:"index" json:"to"` + Subject string `storm:"index" json:"subject"` + Date int64 `storm:"index" json:"date"` + Id string `storm:"id" json:"id"` +}