feat(PROJ-15): CLI Import & Export als Subcommands
- archivmail import: EML + MBOX, --file/--dir/--recursive/--dry-run/--json - archivmail export: EML + MBOX, Filter --from/--to/--date-from/--date-to/--query/--force/--json - archivmail help / version - MBOX Parser (SplitMbox) in pkg/mailparser/mbox.go - Subcommand-Router in main.go ohne externe Abhängigkeit Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
package mailparser
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// SplitMbox splits a raw mbox file into individual RFC 2822 message bytes.
|
||||
// Each message starts with a "From " separator line which is skipped.
|
||||
func SplitMbox(data []byte) [][]byte {
|
||||
var messages [][]byte
|
||||
var current bytes.Buffer
|
||||
|
||||
scanner := bufio.NewScanner(bytes.NewReader(data))
|
||||
scanner.Buffer(make([]byte, 1024*1024), 10*1024*1024)
|
||||
|
||||
inMessage := false
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
// mbox separator: line starts with "From " but not "From:" header
|
||||
if strings.HasPrefix(line, "From ") && !strings.HasPrefix(line, "From: ") {
|
||||
if inMessage && current.Len() > 0 {
|
||||
messages = append(messages, bytes.TrimSpace(current.Bytes()))
|
||||
current.Reset()
|
||||
}
|
||||
inMessage = true
|
||||
continue
|
||||
}
|
||||
if inMessage {
|
||||
// unescape ">From " lines (mbox quoting)
|
||||
if strings.HasPrefix(line, ">From ") {
|
||||
line = line[1:]
|
||||
}
|
||||
current.WriteString(line)
|
||||
current.WriteByte('\n')
|
||||
}
|
||||
}
|
||||
if inMessage && current.Len() > 0 {
|
||||
messages = append(messages, bytes.TrimSpace(current.Bytes()))
|
||||
}
|
||||
return messages
|
||||
}
|
||||
Reference in New Issue
Block a user