Add mbox viewer panes
This commit is contained in:
parent
4e51aee1a9
commit
955c1e0f92
3 changed files with 246 additions and 7 deletions
|
|
@ -3,6 +3,9 @@ package backend
|
|||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime"
|
||||
"net/mail"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
|
@ -71,8 +74,96 @@ type MboxEntry struct {
|
|||
|
||||
// ReadMboxList parst die Kopfzeilen aller Mails einer mbox-Datei (fuer die
|
||||
// Nachrichtenliste). ReadMboxMessage liefert eine einzelne Mail als Rohtext.
|
||||
func ReadMboxList(path string) ([]MboxEntry, error) { return nil, nil } // TODO Codex
|
||||
func ReadMboxMessage(path string, index int) ([]byte, error) { return nil, nil } // TODO Codex
|
||||
func ReadMboxList(path string) ([]MboxEntry, error) {
|
||||
msgs, err := readMboxMessages(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out := make([]MboxEntry, 0, len(msgs))
|
||||
for i, raw := range msgs {
|
||||
msg, err := mail.ReadMessage(bytes.NewReader(raw))
|
||||
if err != nil {
|
||||
out = append(out, MboxEntry{Index: i, From: "(unlesbar)", Subject: "Unlesbare Nachricht"})
|
||||
continue
|
||||
}
|
||||
out = append(out, MboxEntry{
|
||||
Index: i,
|
||||
From: decodeHeader(msg.Header.Get("From")),
|
||||
Subject: decodeHeader(msg.Header.Get("Subject")),
|
||||
Date: decodeHeader(msg.Header.Get("Date")),
|
||||
})
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func ReadMboxMessage(path string, index int) ([]byte, error) {
|
||||
msgs, err := readMboxMessages(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if index < 0 || index >= len(msgs) {
|
||||
return nil, fmt.Errorf("message index out of range")
|
||||
}
|
||||
return msgs[index], nil
|
||||
}
|
||||
|
||||
func readMboxMessages(path string) ([][]byte, error) {
|
||||
b, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b = bytes.ReplaceAll(b, []byte("\r\n"), []byte("\n"))
|
||||
lines := bytes.Split(b, []byte("\n"))
|
||||
var msgs [][]byte
|
||||
var cur bytes.Buffer
|
||||
inMsg := false
|
||||
for _, line := range lines {
|
||||
if bytes.HasPrefix(line, []byte("From ")) {
|
||||
if inMsg && cur.Len() > 0 {
|
||||
msgs = append(msgs, bytes.TrimRight(cur.Bytes(), "\n"))
|
||||
cur.Reset()
|
||||
}
|
||||
inMsg = true
|
||||
continue
|
||||
}
|
||||
if !inMsg {
|
||||
continue
|
||||
}
|
||||
if bytes.HasPrefix(line, []byte(">From ")) {
|
||||
line = line[1:]
|
||||
}
|
||||
_, _ = cur.Write(line)
|
||||
_ = cur.WriteByte('\n')
|
||||
}
|
||||
if inMsg && cur.Len() > 0 {
|
||||
msgs = append(msgs, bytes.TrimRight(cur.Bytes(), "\n"))
|
||||
}
|
||||
return msgs, nil
|
||||
}
|
||||
|
||||
func decodeHeader(v string) string {
|
||||
v = strings.TrimSpace(v)
|
||||
if v == "" {
|
||||
return ""
|
||||
}
|
||||
decoded, err := new(mime.WordDecoder).DecodeHeader(v)
|
||||
if err != nil {
|
||||
return v
|
||||
}
|
||||
return decoded
|
||||
}
|
||||
|
||||
func messageBody(raw []byte) string {
|
||||
msg, err := mail.ReadMessage(bytes.NewReader(raw))
|
||||
if err != nil {
|
||||
return string(raw)
|
||||
}
|
||||
body, err := io.ReadAll(msg.Body)
|
||||
if err != nil {
|
||||
return string(raw)
|
||||
}
|
||||
return string(body)
|
||||
}
|
||||
|
||||
func safeMboxName(folder string) string {
|
||||
folder = strings.TrimSpace(folder)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue