[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Synchronize Gnus and IMAP's notion of read mail
From: |
Andrew Cohen |
Subject: |
Re: Synchronize Gnus and IMAP's notion of read mail |
Date: |
Sat, 22 Jun 2024 18:59:07 +0800 |
User-agent: |
Gnus/5.13 (Gnus v5.13) |
>>>>> "SM" == Stefan Monnier <monnier@iro.umontreal.ca> writes:
SM> Apparently there's a bug in Gnus which causes it to sometimes
SM> fail to tell IMAP that some messages are "read" (or maybe it
SM> causes some messages to be re-set to "unread"? I don't know).
SM> In any case, what I do know is that what my IMAP server
SM> considers as "read" is not the same as what Gnus thinks, even
SM> though I basically never access my IMAP server via anything else
SM> than Gnus.
SM> I have not yet figured out how/why this happens, but instead I'm
SM> wondering how I can fix the consequence of the bug by
SM> re-synchronize Gnus with IMAP.
SM> I know how to get Gnus to forget its own notion of "read" and
SM> (re)fetch all that info from IMAP. But I'd like to do the
SM> reverse: have Gnus tell IMAP which messages should be considered
SM> "read" and which not (of course, being careful not to affect
SM> those messages which Gnus hasn't seen yet). E.g. something like
SM> have Gnus go through all the messages that IMAP say are "unread"
SM> and mark them (in IMAP) as "read" if Gnus thinks they've already
SM> been "read".
WARNING! WARNING! Messing with message marks can be dangerous (that is,
you might lose your marks). I can suggest how to do this (although I
haven't tested it). I would suggest testing on smallish groups where
losing the marks wouldn't be too painful.
The main thing you need is 'gnus-request-set-mark which allows you to
manipulate the marks in the backend. So here is a function (untested)
that takes a list of marks (defaulting to 'read) and installs gnus' current
vision of those marks into the backend, for the messages that gnus knows
about. It does this by deleting the mark from all messages that gnus
knows about, and then setting it for those messages gnus thinks should
have the mark. If there are messages that gnus doesn't know about they
won't be affected (at least this is what SHOULD happen, since the
actions use an explicit list of message UIDS, which can only include
those that gnus knows about).
(defun gnus-override-group-marks (group &optional marks)
"Store gnus marks for GROUP in the backend.
If the list MARKS is non-nil, set these specific marks; otherwise set
only read and unread status."
(let ((marks (or marks '(read)))
(active (gnus-active group))
(info-marks (gnus-info-marks (gnus-get-info group)))
action)
(dolist (mark marks)
(if (eq mark 'read)
(push (list (gnus-info-read (gnus-get-info group))
'add (list mark)) action)
(push (list (cdr (assq mark info-marks)) 'add (list mark)) action)))
;; wipe out existing marks
(gnus-request-set-mark group (list (list active 'del marks)))
;; add gnus version of marks
(gnus-request-set-mark group action)))
If you want to know what the imap server thinks the marks are you can do
this (replace server and group with your values):
(mapcar (lambda (n) (elt n 1))
(gnus-search-run-query '((search-query-spec (query . "not mark:read"))
(search-group-spec ("server" "group")))))
(remove the "not" to find what the imap server thinks are the read articles).
Best,
Andy
--
Andrew Cohen