sophuwu.site > mailboxxer   
              121
            
             package main

import (
	"bytes"
	"crypto/sha1"
	"encoding/base32"
	"fmt"
	"github.com/andybalholm/brotli"
	"mime"
	"net/mail"
	"os"
	"time"
)

func Brotli(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() (EmailMeta, bytes.Buffer) {
	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
	err = Brotli(&email)
	if err != nil {
		os.Exit(1)
	}
	return meta, email
}

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()
}
func ShaHash(b []byte) string {
	h := sha1.New()
	h.Write(b)
	return base32.StdEncoding.EncodeToString(h.Sum(nil))
}

// 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 = ShaHash(email.Bytes())
	em.Subject = "No Subject"

	decode := func(d mime.WordDecoder) func(s *string) {
		return func(s *string) {
			if ss, ers := d.DecodeHeader(fmt.Sprintf(*s)); ers == nil {
				*s = ss
			}
		}
	}(mime.WordDecoder{})

	e, err := mail.ReadMessage(bytes.NewReader(email.Bytes()))
	if err != nil {
		return em, err
	}

	em.To = func() string {
		if len(e.Header.Get("To")) > 0 {
			return e.Header.Get("To")
		}
		if len(e.Header.Get("X-Original-To")) > 2 {
			return e.Header.Get("X-Original-To")
		}
		if e.Header.Get("Delivered-To") != "" {
			return e.Header.Get("Delivered-To")
		}
		return "Unknown Recipient"
	}()
	decode(&em.To)
	em.From = func() string {
		if len(e.Header.Get("From")) > 0 {
			return e.Header.Get("From")
		}
		if len(e.Header.Get("Return-Path")) > 2 {
			return e.Header.Get("Return-Path")
		}
		if e.Header.Get("Sender") != "" {
			return e.Header.Get("Sender")
		}
		return "Unknown Sender"
	}()
	decode(&em.From)
	if s := e.Header.Get("Subject"); s != "" {
		em.Subject = s
	}
	decode(&em.Subject)
	em.Date = dateHeader(&e.Header)

	return em, nil
}

// EmailMeta contains the fields that will be searchable in the database
type EmailMeta struct {
	From    string
	To      string
	Subject string
	Date    int64
	Id      string
}