~sircmpwn/aerc

Render non passable email in msglist v1 PROPOSED

Reto Brunner: 1
 Render non passable email in msglist

 8 files changed, 53 insertions(+), 14 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~sircmpwn/aerc/patches/14202/mbox | git am -3
Learn more about email & git
View this thread in the archives

[PATCH] Render non passable email in msglist Export this patch

While we can't display such messages, nor sort them in any sensible manner,
we can at least make the spinner go away.

For this to work this commit makes the sort functionality tolerant of nil envelopes.
Further both the notmuch and maildir worker now return a msgInfo even if the mail
can't be parsed.

The point of this is that one a stops the spinner, allows the rendering of other
messages to continue and one can pipe the message via :pipe -m to something
like less.
---

Any feedback / testing would be appreciated, is there something missing?
Do we need to make this more robust? We could render a nice screen same as if we
don't have a filter for a mime type.... but for now that should be a good start I
think.


 commands/msg/pipe.go      |  7 +++++--
 lib/msgstore.go           |  2 +-
 widgets/msglist.go        | 20 ++++++++++++++++++--
 worker/lib/sort.go        | 15 +++++++++++++++
 worker/maildir/message.go |  9 ++++++++-
 worker/maildir/worker.go  |  2 --
 worker/notmuch/message.go |  6 +++++-
 worker/notmuch/worker.go  |  6 +-----
 8 files changed, 53 insertions(+), 14 deletions(-)

diff --git a/commands/msg/pipe.go b/commands/msg/pipe.go
index 4e4ba67..2305c1d 100644
--- a/commands/msg/pipe.go
+++ b/commands/msg/pipe.go
@@ -120,8 +120,11 @@ func (Pipe) Execute(aerc *widgets.Aerc, args []string) error {
			if background {
				doExec(fm.Content.Reader)
			} else {
				doTerm(fm.Content.Reader, fmt.Sprintf(
					"%s <%s", cmd[0], msg.Envelope.Subject))
				title := fmt.Sprintf("msg:%d", msg.Uid)
				if msg.Envelope != nil {
					title = fmt.Sprintf("%s <%s", cmd[0], msg.Envelope.Subject)
				}
				doTerm(fm.Content.Reader, title)
			}
		})
	} else if pipePart {
diff --git a/lib/msgstore.go b/lib/msgstore.go
index b95b68f..0584d69 100644
--- a/lib/msgstore.go
+++ b/lib/msgstore.go
@@ -207,7 +207,7 @@ func (store *MessageStore) Update(msg types.WorkerMessage) {
		if !seen && recent {
			store.triggerNewEmail(msg.Info)
		}
		if _, ok := store.pendingHeaders[msg.Info.Uid]; msg.Info.Envelope != nil && ok {
		if _, ok := store.pendingHeaders[msg.Info.Uid]; ok {
			delete(store.pendingHeaders, msg.Info.Uid)
			if cbs, ok := store.headerCallbacks[msg.Info.Uid]; ok {
				for _, cb := range cbs {
diff --git a/widgets/msglist.go b/widgets/msglist.go
index 09b0868..e2b3e26 100644
--- a/widgets/msglist.go
+++ b/widgets/msglist.go
@@ -102,10 +102,14 @@ func (ml *MessageList) Draw(ctx *ui.Context) {
			continue
		}

		var subject string
		if msg != nil && msg.Envelope != nil {
			subject = msg.Envelope.Subject
		}
		uiConfig := ml.conf.GetUiConfig(map[config.ContextType]string{
			config.UI_CONTEXT_ACCOUNT: ml.aerc.SelectedAccount().AccountConfig().Name,
			config.UI_CONTEXT_FOLDER:  ml.aerc.SelectedAccount().Directories().Selected(),
			config.UI_CONTEXT_SUBJECT: msg.Envelope.Subject,
			config.UI_CONTEXT_SUBJECT: subject,
		})

		so := config.STYLE_MSGLIST_DEFAULT
@@ -144,10 +148,22 @@ func (ml *MessageList) Draw(ctx *ui.Context) {
		style := uiConfig.GetStyle(so)

		// current row
		if row == ml.store.SelectedIndex()-ml.scroll {
		isCurrentRow := row == ml.store.SelectedIndex()-ml.scroll
		if isCurrentRow {
			style = uiConfig.GetStyleSelected(so)
		}

		if msg.Error != nil {
			style := uiConfig.GetStyle(config.STYLE_ERROR).Reverse(isCurrentRow)
			em := runewidth.Truncate(
				fmt.Sprintf("invalid email: %d", msg.Uid),
				ctx.Width(), "...")
			txt := ui.NewText(em, style).Strategy(ui.TEXT_CENTER)
			txt.Draw(ctx.Subcontext(0, row, textWidth, 1))
			row += 1
			continue
		}

		ctx.Fill(0, row, ctx.Width(), 1, ' ', style)
		fmtStr, args, err := format.ParseMessageFormat(
			ml.aerc.SelectedAccount().acct.From,
diff --git a/worker/lib/sort.go b/worker/lib/sort.go
index 9d1f50a..8beb992 100644
--- a/worker/lib/sort.go
+++ b/worker/lib/sort.go
@@ -16,6 +16,10 @@ func Sort(messageInfos []*models.MessageInfo,
		switch criterion.Field {
		case types.SortArrival:
			sortSlice(criterion, messageInfos, func(i, j int) bool {
				if messageInfos[i].Envelope == nil ||
					messageInfos[j].Envelope == nil {
					return false
				}
				return messageInfos[i].InternalDate.Before(messageInfos[j].InternalDate)
			})
		case types.SortCc:
@@ -25,6 +29,10 @@ func Sort(messageInfos []*models.MessageInfo,
				})
		case types.SortDate:
			sortSlice(criterion, messageInfos, func(i, j int) bool {
				if messageInfos[i].Envelope == nil ||
					messageInfos[j].Envelope == nil {
					return false
				}
				return messageInfos[i].Envelope.Date.Before(messageInfos[j].Envelope.Date)
			})
		case types.SortFrom:
@@ -41,6 +49,9 @@ func Sort(messageInfos []*models.MessageInfo,
		case types.SortSubject:
			sortStrings(messageInfos, criterion,
				func(msgInfo *models.MessageInfo) string {
					if msgInfo.Envelope == nil {
						return ""
					}
					subject := strings.ToLower(msgInfo.Envelope.Subject)
					subject = strings.TrimPrefix(subject, "re: ")
					return strings.TrimPrefix(subject, "fwd: ")
@@ -63,6 +74,10 @@ func Sort(messageInfos []*models.MessageInfo,
func sortAddresses(messageInfos []*models.MessageInfo, criterion *types.SortCriterion,
	getValue func(*models.MessageInfo) []*models.Address) {
	sortSlice(criterion, messageInfos, func(i, j int) bool {
		if messageInfos[i].Envelope == nil ||
			messageInfos[j].Envelope == nil {
			return false
		}
		addressI, addressJ := getValue(messageInfos[i]), getValue(messageInfos[j])
		var firstI, firstJ *models.Address
		if len(addressI) > 0 {
diff --git a/worker/maildir/message.go b/worker/maildir/message.go
index 55e2613..5df8e8f 100644
--- a/worker/maildir/message.go
+++ b/worker/maildir/message.go
@@ -85,7 +85,14 @@ func (m Message) Remove() error {

// MessageInfo populates a models.MessageInfo struct for the message.
func (m Message) MessageInfo() (*models.MessageInfo, error) {
	return lib.MessageInfo(m)
	info, err := lib.MessageInfo(m)
	if info == nil {
		info = &models.MessageInfo{
			Uid:   m.uid,
			Error: err,
		}
	}
	return info, err
}

// NewBodyPartReader creates a new io.Reader for the requested body part(s) of
diff --git a/worker/maildir/worker.go b/worker/maildir/worker.go
index 4a7ae51..64e89e0 100644
--- a/worker/maildir/worker.go
+++ b/worker/maildir/worker.go
@@ -386,8 +386,6 @@ func (w *Worker) handleFetchMessageHeaders(
		info, err := m.MessageInfo()
		if err != nil {
			w.worker.Logger.Printf("could not get message info: %v", err)
			w.err(msg, err)
			continue
		}
		w.worker.PostMessage(&types.MessageInfo{
			Message: types.RespondTo(msg),
diff --git a/worker/notmuch/message.go b/worker/notmuch/message.go
index 82d00f3..78ce93f 100644
--- a/worker/notmuch/message.go
+++ b/worker/notmuch/message.go
@@ -42,7 +42,11 @@ func (m *Message) NewReader() (io.Reader, error) {

// MessageInfo populates a models.MessageInfo struct for the message.
func (m *Message) MessageInfo() (*models.MessageInfo, error) {
	return lib.MessageInfo(m)
	info, err := lib.MessageInfo(m)
	if info == nil {
		info = &models.MessageInfo{Uid: m.uid, Error: err}
	}
	return info, err
}

// NewBodyPartReader creates a new io.Reader for the requested body part(s) of
diff --git a/worker/notmuch/worker.go b/worker/notmuch/worker.go
index 67888ff..35e6690 100644
--- a/worker/notmuch/worker.go
+++ b/worker/notmuch/worker.go
@@ -530,14 +530,11 @@ func (w *worker) emitDirectoryContents(parent types.WorkerMessage) error {
func (w *worker) emitMessageInfo(m *Message,
	parent types.WorkerMessage) error {
	info, err := m.MessageInfo()
	if err != nil {
		return fmt.Errorf("could not get MessageInfo: %v", err)
	}
	w.w.PostMessage(&types.MessageInfo{
		Message: types.RespondTo(parent),
		Info:    info,
	}, nil)
	return nil
	return err
}

func (w *worker) emitLabelList() {
@@ -564,7 +561,6 @@ func (w *worker) sort(uids []uint32,
		info, err := m.MessageInfo()
		if err != nil {
			w.w.Logger.Printf("could not get message info: %v", err)
			continue
		}
		msgInfos = append(msgInfos, info)
	}
-- 
2.28.0
Typo... was to quick to accept the auto correct... parseable?
Vim is still yelling at me though... in any case:
"horribly broken, non compliant mail"

You get the gist...