emacs-devel
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]