refactor: remove webmail interface, focus on core mail storage functionality

- Remove obsolete CouchDB design documents (webmail.json, dashboard.json)
- Clean up webmail-related code from couch/couch.go (WebmailViews, CreateWebmailViews, etc.)
- Update documentation to focus on core mail-to-CouchDB storage functionality
- Add Future Plans section describing planned webmail viewer as separate component
- Apply go fmt formatting and ensure code quality standards
- Update test documentation to show raw CouchDB API access patterns
- Remove compiled binary from repository

This refactor simplifies the codebase to focus on its core purpose: efficiently
backing up emails from IMAP to CouchDB. The webmail interface will be developed
as a separate, optional component to maintain clean separation of concerns.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Ole-Morten Duesund 2025-08-02 14:57:51 +02:00
commit e280aa0aaa
12 changed files with 147 additions and 49 deletions

View file

@ -104,7 +104,7 @@ func (c *ImapClient) GetMessages(mailbox string, since *time.Time, maxMessages i
// First, get all current UIDs in the mailbox for sync purposes
allUIDsSet := imap.SeqSet{}
allUIDsSet.AddRange(1, mbox.NumMessages)
// Fetch UIDs for all messages to track current state
uidCmd := c.Fetch(allUIDsSet, &imap.FetchOptions{UID: true})
for {
@ -112,12 +112,12 @@ func (c *ImapClient) GetMessages(mailbox string, since *time.Time, maxMessages i
if msg == nil {
break
}
data, err := msg.Collect()
if err != nil {
continue
}
if data.UID != 0 {
currentUIDs[uint32(data.UID)] = true
}
@ -126,13 +126,13 @@ func (c *ImapClient) GetMessages(mailbox string, since *time.Time, maxMessages i
// Determine which messages to fetch based on since date
var seqSet imap.SeqSet
if since != nil {
// Use IMAP SEARCH to find messages since the specified date
searchCriteria := &imap.SearchCriteria{
Since: *since,
}
searchCmd := c.Search(searchCriteria, nil)
searchResults, err := searchCmd.Wait()
if err != nil {
@ -149,12 +149,12 @@ func (c *ImapClient) GetMessages(mailbox string, since *time.Time, maxMessages i
if len(searchSeqNums) == 0 {
return []*Message{}, currentUIDs, nil
}
// Limit results if maxMessages is specified
if maxMessages > 0 && len(searchSeqNums) > maxMessages {
searchSeqNums = searchSeqNums[len(searchSeqNums)-maxMessages:]
}
for _, seqNum := range searchSeqNums {
seqSet.AddNum(seqNum)
}
@ -165,11 +165,11 @@ func (c *ImapClient) GetMessages(mailbox string, since *time.Time, maxMessages i
if maxMessages > 0 && int(numToFetch) > maxMessages {
numToFetch = uint32(maxMessages)
}
if numToFetch == 0 {
return []*Message{}, currentUIDs, nil
}
// Fetch the most recent messages
seqSet.AddRange(mbox.NumMessages-numToFetch+1, mbox.NumMessages)
}
@ -177,12 +177,12 @@ func (c *ImapClient) GetMessages(mailbox string, since *time.Time, maxMessages i
// Fetch message data - get envelope and full message body
options := &imap.FetchOptions{
Envelope: true,
UID: true,
UID: true,
BodySection: []*imap.FetchItemBodySection{
{}, // Empty section gets the entire message
},
}
fetchCmd := c.Fetch(seqSet, options)
for {
@ -196,12 +196,12 @@ func (c *ImapClient) GetMessages(mailbox string, since *time.Time, maxMessages i
log.Printf("Failed to parse message: %v", err)
continue
}
// Apply message-level keyword filtering
if messageFilter != nil && !c.ShouldProcessMessage(parsedMsg, messageFilter) {
continue // Skip this message due to keyword filter
}
messages = append(messages, parsedMsg)
}
@ -231,7 +231,7 @@ func (c *ImapClient) parseMessage(fetchMsg *imapclient.FetchMessageData) (*Messa
env := buffer.Envelope
msg.Subject = env.Subject
msg.Date = env.Date
// Parse From addresses
for _, addr := range env.From {
if addr.Mailbox != "" {
@ -242,7 +242,7 @@ func (c *ImapClient) parseMessage(fetchMsg *imapclient.FetchMessageData) (*Messa
msg.From = append(msg.From, fullAddr)
}
}
// Parse To addresses
for _, addr := range env.To {
if addr.Mailbox != "" {
@ -264,7 +264,7 @@ func (c *ImapClient) parseMessage(fetchMsg *imapclient.FetchMessageData) (*Messa
if len(buffer.BodySection) > 0 {
bodyBuffer := buffer.BodySection[0]
reader := bytes.NewReader(bodyBuffer.Bytes)
// Parse the message using go-message
entity, err := message.Read(reader)
if err != nil {
@ -338,7 +338,7 @@ func (c *ImapClient) parseMessagePart(entity *message.Entity, msg *Message) erro
disposition, dispositionParams, _ := entity.Header.ContentDisposition()
// Determine if this is an attachment
isAttachment := disposition == "attachment" ||
isAttachment := disposition == "attachment" ||
(disposition == "inline" && dispositionParams["filename"] != "") ||
params["name"] != ""