From 2be18f96bd05dd54cfa55145558b9fee18960c89 Mon Sep 17 00:00:00 2001 From: teranisi Date: Mon, 2 Oct 2000 02:52:14 +0000 Subject: [PATCH] * elmo-util.el (elmo-buffer-field-primitive-condition-match): Fixed. * elmo-nntp.el (elmo-nntp-default-use-xhdr): New variable. (elmo-nntp-xhdr-p): New macro. (elmo-nntp-set-xhdr): Ditto. (elmo-nntp-parse-xhdr-response): New function. (elmo-nntp-retrieve-field): Ditto. (elmo-nntp-search-primitive): Ditto. (elmo-nntp-search): Implemented. * elmo-date.el (elmo-date-make-sortable-string): New macro. * elmo-archive.el (elmo-archive-search): Set all number list to `elmo-archive-field-condition-match' * elmo-localdir.el (elmo-localdir-search): Likewise. * elmo-maildir.el (elmo-maildir-search): Likewise. --- elmo/ChangeLog | 21 ++++++++ elmo/elmo-archive.el | 5 +- elmo/elmo-date.el | 8 +++ elmo/elmo-localdir.el | 6 ++- elmo/elmo-maildir.el | 5 +- elmo/elmo-nntp.el | 139 ++++++++++++++++++++++++++++++++++++++++++++++++- elmo/elmo-util.el | 4 +- 7 files changed, 178 insertions(+), 10 deletions(-) diff --git a/elmo/ChangeLog b/elmo/ChangeLog index 616bcfb..4353298 100644 --- a/elmo/ChangeLog +++ b/elmo/ChangeLog @@ -1,3 +1,24 @@ +2000-10-02 Yuuichi Teranishi + + * elmo-util.el (elmo-buffer-field-primitive-condition-match): Fixed. + + * elmo-nntp.el (elmo-nntp-default-use-xhdr): New variable. + (elmo-nntp-xhdr-p): New macro. + (elmo-nntp-set-xhdr): Ditto. + (elmo-nntp-parse-xhdr-response): New function. + (elmo-nntp-retrieve-field): Ditto. + (elmo-nntp-search-primitive): Ditto. + (elmo-nntp-search): Implemented. + + * elmo-date.el (elmo-date-make-sortable-string): New macro. + + * elmo-archive.el (elmo-archive-search): Set all number list to + `elmo-archive-field-condition-match' + + * elmo-localdir.el (elmo-localdir-search): Likewise. + + * elmo-maildir.el (elmo-maildir-search): Likewise. + 2000-10-01 OKAZAKI Tetsurou * elmo-msgdb.el (elmo-living-messages): New function. diff --git a/elmo/elmo-archive.el b/elmo/elmo-archive.el index 9f6c2ef..0fb7ed0 100644 --- a/elmo/elmo-archive.el +++ b/elmo/elmo-archive.el @@ -990,9 +990,10 @@ TYPE specifies the archiver's symbol." (num (length msgs)) (i 0) (case-fold-search nil) - ret-val) + number-list ret-val) + (setq number-list msgs) (while msgs - (if (elmo-archive-field-condition-match spec (car msgs) msgs + (if (elmo-archive-field-condition-match spec (car msgs) number-list condition (nth 3 spec)) (setq ret-val (cons (car msgs) ret-val))) diff --git a/elmo/elmo-date.el b/elmo/elmo-date.el index 5e8ad89..02d4c5f 100644 --- a/elmo/elmo-date.el +++ b/elmo/elmo-date.el @@ -138,6 +138,14 @@ "0:00") (cadr timezone)) nil nil))) +(defmacro elmo-date-make-sortable-string (datevec) + "Make a sortable string from DATEVEC." + (` (timezone-make-sortable-date + (aref (, datevec) 0) + (aref (, datevec) 1) + (aref (, datevec) 2) + (aref (, datevec) 3)))) + (provide 'elmo-date) ;;; elmo-date.el ends here diff --git a/elmo/elmo-localdir.el b/elmo/elmo-localdir.el index 9e05370..55be0ef 100644 --- a/elmo/elmo-localdir.el +++ b/elmo/elmo-localdir.el @@ -363,10 +363,12 @@ (defun elmo-localdir-search (spec condition &optional from-msgs) (let* ((msgs (or from-msgs (elmo-localdir-list-folder spec))) (num (length msgs)) - (i 0) case-fold-search ret-val) + (i 0) + number-list case-fold-search ret-val) + (setq number-list msgs) (while msgs (if (elmo-localdir-field-condition-match spec condition - (car msgs) msgs) + (car msgs) number-list) (setq ret-val (cons (car msgs) ret-val))) (when (> num elmo-display-progress-threshold) (setq i (1+ i)) diff --git a/elmo/elmo-maildir.el b/elmo/elmo-maildir.el index 54983bf..9b2e6ec 100644 --- a/elmo/elmo-maildir.el +++ b/elmo/elmo-maildir.el @@ -429,13 +429,14 @@ file name for maildir directories." case-fold-search ret-val percent num (num (length msgs)) - msg-num) + number-list msg-num) + (setq number-list msgs) (while msgs (setq msg-num (car msgs)) (if (elmo-file-field-condition-match (elmo-maildir-number-to-filename dir (car msgs) loc-alist) - condition (car msgs) msgs) + condition (car msgs) number-list) (setq ret-val (append ret-val (list msg-num)))) (setq i (1+ i)) (setq percent (/ (* i 100) num)) diff --git a/elmo/elmo-nntp.el b/elmo/elmo-nntp.el index e9a6e0c..2ecba97 100644 --- a/elmo/elmo-nntp.el +++ b/elmo/elmo-nntp.el @@ -71,6 +71,8 @@ Don't cache if nil.") (defvar elmo-nntp-default-use-list-active t) +(defvar elmo-nntp-default-use-xhdr t) + (defvar elmo-nntp-server-command-alist nil) @@ -141,6 +143,16 @@ Don't cache if nil.") (defmacro elmo-nntp-set-list-active (server port value) (` (elmo-nntp-set-server-command (, server) (, port) 'list-active (, value)))) +(defmacro elmo-nntp-xhdr-p (server port) + (` (let ((entry (elmo-nntp-get-server-command (, server) (, port)))) + (if entry + (aref (cdr entry) + (cdr (assq 'xhdr elmo-nntp-server-command-index))) + elmo-nntp-default-use-xhdr)))) + +(defmacro elmo-nntp-set-xhdr (server port value) + (` (elmo-nntp-set-server-command (, server) (, port) 'xhdr (, value)))) + (defsubst elmo-nntp-max-number-precedes-list-active-p () elmo-nntp-max-number-precedes-list-active) @@ -818,6 +830,19 @@ Don't cache if nil.") (kill-buffer tmp-buffer) ret-val)) +(defun elmo-nntp-parse-xhdr-response (string) + (let (response) + (with-temp-buffer + (insert string) + (goto-char (point-min)) + (while (not (eobp)) + (if (looking-at "^\\([0-9]+\\) \\(.*\\)$") + (setq response (cons (cons (string-to-int (elmo-match-buffer 1)) + (elmo-match-buffer 2)) + response))) + (forward-line 1))) + (nreverse response))) + (defun elmo-nntp-parse-overview-string (string) (save-excursion (let ((tmp-buffer (get-buffer-create " *ELMO Overview TMP*")) @@ -1122,9 +1147,119 @@ Return nil if connection failed." (defun elmo-nntp-create-folder (spec) nil) ; noop +(defun elmo-nntp-retrieve-field (spec field from-msgs) + "Retrieve FIELD values from FROM-MSGS. +Returns a list of cons cells like (NUMBER . VALUE)" + (let* ((type (elmo-nntp-spec-stream-type spec)) + (port (elmo-nntp-spec-port spec)) + (user (elmo-nntp-spec-username spec)) + (server (elmo-nntp-spec-hostname spec)) + (folder (elmo-nntp-spec-group spec)) + (connection (elmo-nntp-get-connection server user port type)) + (cwf (caddr connection)) + (buffer (car connection)) + (process (cadr connection))) + (if (elmo-nntp-xhdr-p server port) + (progn + (if (and folder + (not (string= cwf folder)) + (null (elmo-nntp-goto-folder + server folder user port type))) + (error "group %s not found" folder)) + (elmo-nntp-send-command buffer process + (format "xhdr %s %s" + field + (if from-msgs + (format + "%d-%d" + (car from-msgs) + (nth + (max + (- (length from-msgs) 1) 0) + from-msgs)) + "0-"))) + (if (elmo-nntp-read-response buffer process t) + (elmo-nntp-parse-xhdr-response + (elmo-nntp-read-contents buffer process)) + (elmo-nntp-set-xhdr server port nil) + (error "NNTP XHDR command failed")))))) + +(defun elmo-nntp-search-primitive (spec condition &optional from-msgs) + (let ((search-key (elmo-filter-key condition))) + (cond + ((string= "last" search-key) + (let ((numbers (or from-msgs (elmo-nntp-list-folder spec)))) + (nthcdr (max (- (length numbers) + (string-to-int (elmo-filter-value condition))) + 0) + numbers))) + ((string= "first" search-key) + (let* ((numbers (or from-msgs (elmo-nntp-list-folder spec))) + (rest (nthcdr (string-to-int (elmo-filter-value condition) ) + numbers))) + (mapcar '(lambda (x) (delete x numbers)) rest) + numbers)) + ((or (string= "since" search-key) + (string= "before" search-key)) + (let* ((key-date (elmo-date-get-datevec (elmo-filter-value condition))) + (key-datestr (elmo-date-make-sortable-string key-date)) + (since (string= "since" search-key)) + result) + (setq result + (delq nil + (mapcar + (lambda (pair) + (if (if since + (string< key-datestr + (elmo-date-make-sortable-string + (timezone-fix-time + (cdr pair) + (current-time-zone) nil))) + (not (string< key-datestr + (elmo-date-make-sortable-string + (timezone-fix-time + (cdr pair) + (current-time-zone) nil))))) + (car pair))) + (elmo-nntp-retrieve-field spec "date" from-msgs)))) + (if from-msgs + (elmo-list-filter from-msgs result) + result))) + (t + (let ((val (elmo-filter-value condition)) + (case-fold-search t) + result) + (setq result + (delq nil + (mapcar + (lambda (pair) + (if (string-match val (cdr pair)) + (car pair))) + (elmo-nntp-retrieve-field spec search-key + from-msgs)))) + (if from-msgs + (elmo-list-filter from-msgs result) + result)))))) + (defun elmo-nntp-search (spec condition &optional from-msgs) - (error "Search by %s for %s is not implemented yet." condition (car spec)) - nil) + (let (result) + (cond + ((vectorp condition) + (setq result (elmo-nntp-search-primitive + spec condition from-msgs))) + ((eq (car condition) 'and) + (setq result (elmo-nntp-search spec (nth 1 condition) from-msgs) + result (elmo-list-filter result + (elmo-nntp-search + spec (nth 2 condition) + from-msgs)))) + ((eq (car condition) 'or) + (setq result (elmo-nntp-search spec (nth 1 condition) from-msgs) + result (elmo-uniq-list + (nconc result + (elmo-nntp-search spec (nth 2 condition) + from-msgs))) + result (sort result '<)))))) (defun elmo-nntp-get-folders-info-prepare (spec connection-keys) (condition-case () diff --git a/elmo/elmo-util.el b/elmo/elmo-util.el index 174198a..40e23eb 100644 --- a/elmo/elmo-util.el +++ b/elmo/elmo-util.el @@ -1216,8 +1216,8 @@ Otherwise treat \\ in NEWTEXT string as special: (goto-char (point-min)) (cond ((string= (elmo-filter-key condition) "last") - (setq result (> (length (memq number number-list)) - (string-to-int (elmo-filter-value condition))))) + (setq result (<= (length (memq number number-list)) + (string-to-int (elmo-filter-value condition))))) ((string= (elmo-filter-key condition) "first") (setq result (< (- (length number-list) (length (memq number number-list))) -- 1.7.10.4