Function: nnmaildir--update-nov
nnmaildir--update-nov is a byte-compiled function defined in
nnmaildir.el.gz.
Signature
(nnmaildir--update-nov SERVER GROUP ARTICLE)
Source Code
;; Defined in /usr/src/emacs/lisp/gnus/nnmaildir.el.gz
(defun nnmaildir--update-nov (server group article)
(let ((nnheader-file-coding-system 'undecided)
(srv-dir (nnmaildir--srv-dir server))
(storage-version 1) ;; [version article-number msgid [...nov...]]
dir gname pgname msgdir prefix suffix file attr mtime novdir novfile
nov msgid nov-beg nov-mid nov-end field val old-extra num
deactivate-mark)
(catch 'return
(setq gname (nnmaildir--grp-name group)
pgname (nnmaildir--pgname server gname)
dir (nnmaildir--srvgrp-dir srv-dir gname)
msgdir (if (nnmaildir--param pgname 'read-only)
(nnmaildir--new dir) (nnmaildir--cur dir))
prefix (nnmaildir--art-prefix article)
suffix (nnmaildir--art-suffix article)
file (concat msgdir prefix suffix)
attr (file-attributes file))
(unless attr
(nnmaildir--expired-article group article)
(throw 'return nil))
(setq mtime (file-attribute-modification-time attr)
attr (file-attribute-size attr)
nov (nnmaildir--art-nov article)
dir (nnmaildir--nndir dir)
novdir (nnmaildir--nov-dir dir)
novfile (concat novdir prefix))
(unless (equal nnmaildir--extra nnmail-extra-headers)
(setq nnmaildir--extra (copy-sequence nnmail-extra-headers)))
(nnmaildir--with-nov-buffer
;; First we'll check for already-parsed NOV data.
(cond ((not (file-exists-p novfile))
;; The NOV file doesn't exist; we have to parse the message.
(setq nov nil))
((not nov)
;; The file exists, but the data isn't in memory; read the file.
(erase-buffer)
(nnheader-insert-file-contents novfile)
(setq nov (read (current-buffer)))
(if (not (and (vectorp nov)
(/= 0 (length nov))
(equal storage-version (aref nov 0))))
;; This NOV data seems to be in the wrong format.
(setq nov nil)
(unless (nnmaildir--art-num article)
(setf (nnmaildir--art-num article) (aref nov 1)))
(unless (nnmaildir--art-msgid article)
(setf (nnmaildir--art-msgid article) (aref nov 2)))
(setq nov (aref nov 3)))))
;; Now check whether the already-parsed data (if we have any) is
;; usable: if the message has been edited or if nnmail-extra-headers
;; has been augmented since this data was parsed from the message,
;; then we have to reparse. Otherwise it's up-to-date.
(when (and nov (equal mtime (nnmaildir--nov-get-mtime nov)))
;; The timestamp matches. Now check nnmail-extra-headers.
(setq old-extra (nnmaildir--nov-get-extra nov))
(when (equal nnmaildir--extra old-extra) ;; common case
;; Save memory; use a single copy of the list value.
(nnmaildir--nov-set-extra nov nnmaildir--extra)
(throw 'return nov))
;; They're not equal, but maybe the new is a subset of the old.
(if (null nnmaildir--extra)
;; The empty set is a subset of every set.
(throw 'return nov))
(if (not (memq nil (mapcar (lambda (e) (memq e old-extra))
nnmaildir--extra)))
(throw 'return nov)))
;; Parse the NOV data out of the message.
(erase-buffer)
(nnheader-insert-file-contents file)
(insert "\n")
(goto-char (point-min))
(save-restriction
(if (search-forward "\n\n" nil 'noerror)
(progn
(setq nov-mid (count-lines (point) (point-max)))
(narrow-to-region (point-min) (1- (point))))
(setq nov-mid 0))
(goto-char (point-min))
(delete-char 1)
(setq nov (nnheader-parse-head t)
field (or (mail-header-lines nov) 0)))
(unless (or (<= field 0) (nnmaildir--param pgname 'distrust-Lines:))
(setq nov-mid field))
(setq nov-mid (number-to-string nov-mid)
nov-mid (concat (number-to-string attr) "\t" nov-mid))
(save-match-data
(setq field (or (mail-header-references nov) ""))
(nnmaildir--tab-to-space field)
(setq nov-mid (concat field "\t" nov-mid)
nov-beg (mapconcat
(lambda (f) (nnmaildir--tab-to-space (or f "")))
(list (mail-header-subject nov)
(mail-header-from nov)
(mail-header-date nov)) "\t")
nov-end (mapconcat
(lambda (extra)
(setq field (symbol-name (car extra))
val (cdr extra))
(nnmaildir--tab-to-space field)
(nnmaildir--tab-to-space val)
(concat field ": " val))
(mail-header-extra nov) "\t")))
(setq msgid (mail-header-id nov))
(if (or (null msgid) (nnheader-fake-message-id-p msgid))
(setq msgid (concat "<" prefix "@nnmaildir>")))
(nnmaildir--tab-to-space msgid)
;; The data is parsed; create an nnmaildir NOV structure.
(setq nov (nnmaildir--nov-new nov-beg nov-mid nov-end mtime
nnmaildir--extra)
num (nnmaildir--art-num article))
(unless num
(setq num (nnmaildir--new-number dir))
(setf (nnmaildir--art-num article) num))
;; Store this new NOV data in a file
(erase-buffer)
(prin1 (vector storage-version num msgid nov) (current-buffer))
(setq file (concat novfile ":"))
(nnmaildir--unlink file)
(write-region (point-min) (point-max) file nil 'no-message nil
'excl))
(rename-file file novfile 'replace)
(setf (nnmaildir--art-msgid article) msgid)
nov)))