Load messages from selected source folder
This commit is contained in:
parent
737343b66b
commit
2f337ee200
1 changed files with 105 additions and 2 deletions
|
|
@ -1,11 +1,13 @@
|
||||||
package backend
|
package backend
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"html"
|
"html"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/mail"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
@ -39,6 +41,8 @@ func RegisterRoutes(mux *http.ServeMux) {
|
||||||
mux.HandleFunc("/transfer", transferHandler)
|
mux.HandleFunc("/transfer", transferHandler)
|
||||||
mux.HandleFunc("/transfer/", transferHandler)
|
mux.HandleFunc("/transfer/", transferHandler)
|
||||||
mux.HandleFunc("/boxes/source", emailBoxHandler)
|
mux.HandleFunc("/boxes/source", emailBoxHandler)
|
||||||
|
mux.HandleFunc("/boxes/source/messages", sourceMailboxMessagesHandler)
|
||||||
|
mux.HandleFunc("/boxes/source/message", sourceMailboxMessageHandler)
|
||||||
mux.HandleFunc("/boxes/target", emailBoxHandler)
|
mux.HandleFunc("/boxes/target", emailBoxHandler)
|
||||||
mux.HandleFunc("/migrate/run", migrateRunHandler) // TODO Codex: RunMigration im Hintergrund
|
mux.HandleFunc("/migrate/run", migrateRunHandler) // TODO Codex: RunMigration im Hintergrund
|
||||||
mux.HandleFunc("/migrate/status", migrateStatusHandler) // TODO Codex: jobs-Fortschritt (HTMX-Poll)
|
mux.HandleFunc("/migrate/status", migrateStatusHandler) // TODO Codex: jobs-Fortschritt (HTMX-Poll)
|
||||||
|
|
@ -314,6 +318,63 @@ func emailBoxHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sourceMailboxMessagesHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
accountName := strings.TrimSpace(r.URL.Query().Get("source"))
|
||||||
|
folder := strings.TrimSpace(r.URL.Query().Get("folder"))
|
||||||
|
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||||
|
if accountName == "" || folder == "" {
|
||||||
|
fmt.Fprint(w, `<div class="pane-head">Nachrichten</div><div class="ef-empty">Quell-Postfach und Ordner waehlen.</div>`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
account, err := GetAccount(accountName)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(w, `<div class="pane-head">Nachrichten</div><div class="ef-empty">%s</div>`, html.EscapeString(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
messages, err := fetchSourceFolderMessages(account, folder)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(w, `<div class="pane-head">Nachrichten</div><div class="ef-empty">%s</div>`, html.EscapeString(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
renderSourceMailboxMessageList(w, account, folder, messages)
|
||||||
|
}
|
||||||
|
|
||||||
|
func sourceMailboxMessageHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
accountName := strings.TrimSpace(r.URL.Query().Get("source"))
|
||||||
|
folder := strings.TrimSpace(r.URL.Query().Get("folder"))
|
||||||
|
index, err := strconv.Atoi(r.URL.Query().Get("index"))
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "bad index", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
account, err := GetAccount(accountName)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
messages, err := fetchSourceFolderMessages(account, folder)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if index < 0 || index >= len(messages) {
|
||||||
|
http.Error(w, "message index out of range", http.StatusNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
raw := messages[index].Body
|
||||||
|
msg, err := mail.ReadMessage(bytes.NewReader(raw))
|
||||||
|
if err != nil {
|
||||||
|
renderReadPaneWithSource(w, account.Name, folder, "", index, "(unlesbar)", "", "", string(raw))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
renderReadPaneWithSource(w, account.Name, folder, "", index,
|
||||||
|
decodeHeader(msg.Header.Get("Subject")),
|
||||||
|
decodeHeader(msg.Header.Get("From")),
|
||||||
|
decodeHeader(msg.Header.Get("Date")),
|
||||||
|
messageBody(raw),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
func archiveCreateHandler(w http.ResponseWriter, r *http.Request) {
|
func archiveCreateHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
if !requireManager(w, r) {
|
if !requireManager(w, r) {
|
||||||
return
|
return
|
||||||
|
|
@ -920,8 +981,50 @@ func renderSourceFolders(b *strings.Builder, account Account) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for _, folder := range folders {
|
for _, folder := range folders {
|
||||||
fmt.Fprintf(b, `<div class="tree-node folder"><span class="tree-label">%s</span><span class="tree-count">%s</span></div>`,
|
fmt.Fprintf(b, `<a class="tree-node folder" href="#" hx-get="/boxes/source/messages?source=%s&folder=%s" hx-target="#list" hx-swap="innerHTML"><span class="tree-label">%s</span><span class="tree-count">%s</span></a>`,
|
||||||
html.EscapeString(folder.Name), html.EscapeString(strings.Join(folder.Attrs, " ")))
|
urlEsc(account.Name), urlEsc(folder.Name), html.EscapeString(folder.Name), html.EscapeString(strings.Join(folder.Attrs, " ")))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func fetchSourceFolderMessages(account Account, folder string) ([]RawMessage, error) {
|
||||||
|
if accountProto(account) == "pop3" {
|
||||||
|
src, err := OpenPOP3Source(account)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer src.Close()
|
||||||
|
return src.Fetch(folder)
|
||||||
|
}
|
||||||
|
src, err := OpenIMAPSource(account)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer src.Close()
|
||||||
|
return src.Fetch(folder)
|
||||||
|
}
|
||||||
|
|
||||||
|
func renderSourceMailboxMessageList(w http.ResponseWriter, account Account, folder string, messages []RawMessage) {
|
||||||
|
fmt.Fprintf(w, `<div class="pane-head">%s / %s (%d)</div>`, html.EscapeString(account.SrcUser), html.EscapeString(folder), len(messages))
|
||||||
|
for i, raw := range messages {
|
||||||
|
subject := "(ohne Betreff)"
|
||||||
|
from := "(ohne Absender)"
|
||||||
|
date := ""
|
||||||
|
if msg, err := mail.ReadMessage(bytes.NewReader(raw.Body)); err == nil {
|
||||||
|
if v := decodeHeader(msg.Header.Get("Subject")); v != "" {
|
||||||
|
subject = v
|
||||||
|
}
|
||||||
|
if v := decodeHeader(msg.Header.Get("From")); v != "" {
|
||||||
|
from = v
|
||||||
|
}
|
||||||
|
date = decodeHeader(msg.Header.Get("Date"))
|
||||||
|
}
|
||||||
|
fmt.Fprintf(w, `<a class="msg-row" href="#" draggable="true" data-source="%s" data-folder="%s" data-index="%d" hx-get="/boxes/source/message?source=%s&folder=%s&index=%d" hx-target="#read" hx-swap="innerHTML"><span class="msg-from">%s</span><span class="msg-subject">%s</span><span class="msg-date">%s</span></a>`,
|
||||||
|
html.EscapeString(account.Name), html.EscapeString(folder), i,
|
||||||
|
urlEsc(account.Name), urlEsc(folder), i,
|
||||||
|
html.EscapeString(from), html.EscapeString(subject), html.EscapeString(date))
|
||||||
|
}
|
||||||
|
if len(messages) == 0 {
|
||||||
|
fmt.Fprint(w, `<div class="ef-empty">Keine Nachrichten in diesem Quell-Ordner.</div>`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue