* elmo-util.el (elmo-buffer-field-primitive-condition-match): Fixed.
authorteranisi <teranisi>
Mon, 2 Oct 2000 02:52:14 +0000 (02:52 +0000)
committerteranisi <teranisi>
Mon, 2 Oct 2000 02:52:14 +0000 (02:52 +0000)
* 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
elmo/elmo-archive.el
elmo/elmo-date.el
elmo/elmo-localdir.el
elmo/elmo-maildir.el
elmo/elmo-nntp.el
elmo/elmo-util.el

index 616bcfb..4353298 100644 (file)
@@ -1,3 +1,24 @@
+2000-10-02  Yuuichi Teranishi  <teranisi@gohome.org>
+
+       * 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  <okazaki@be.to>
 
        * elmo-msgdb.el (elmo-living-messages): New function.
index 9f6c2ef..0fb7ed0 100644 (file)
@@ -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)))
index 5e8ad89..02d4c5f 100644 (file)
               "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
index 9e05370..55be0ef 100644 (file)
 (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))
index 54983bf..9b2e6ec 100644 (file)
@@ -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))
index e9a6e0c..2ecba97 100644 (file)
@@ -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 ()
index 174198a..40e23eb 100644 (file)
@@ -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)))