Gnus development mailing list
 help / color / mirror / Atom feed
* [patch] gnus agent
@ 2000-07-01 18:24 Simon Josefsson
  2000-07-01 19:25 ` Harry Putnam
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Simon Josefsson @ 2000-07-01 18:24 UTC (permalink / raw)


This patch make all articles eligible for agent download, filtered
only by predicates, instead of the hardcoded algorithm that choses
what to download from unread articles only.

Any agent users that care to verify that this doesn't break anything?

Wouldn't it be nice if there was a OGnus beta branch?  Lars?

2000-07-01  Simon Josefsson  <simon@josefsson.org>

	* gnus-agent.el (gnus-agent-fetch-headers): Make all articles
	eligible for agent download.  Load gnus-agent-article-alist.
	(gnus-category-read): Update default.
	(gnus-category-predicate-alist): Add read.
	(gnus-agent-read-p): New predicate.

	* gnus-sum.el (gnus-update-marks): Don't propagate download and
	unsend flags.

2000-07-01  Simon Josefsson  <simon@josefsson.org>

	* gnus.texi (Category Syntax): Fix.

Index: lisp/gnus-agent.el
===================================================================
RCS file: /usr/local/cvsroot/gnus/lisp/gnus-agent.el,v
retrieving revision 5.53
diff -w -u -r5.53 gnus-agent.el
--- lisp/gnus-agent.el	2000/06/26 20:39:15	5.53
+++ lisp/gnus-agent.el	2000/06/30 18:22:26
@@ -552,9 +552,8 @@
 	       (gnus-agent-method-p gnus-command-method))
       (gnus-agent-load-alist gnus-newsgroup-name)
       ;; First mark all undownloaded articles as undownloaded.
-      (let ((articles (append gnus-newsgroup-unreads
-			      gnus-newsgroup-marked
-			      gnus-newsgroup-dormant))
+      (let ((articles (gnus-uncompress-sequence 
+		       (gnus-active gnus-newsgroup-name)))
 	    article)
 	(while (setq article (pop articles))
 	  (unless (or (cdr (assq article gnus-agent-article-alist))
@@ -867,21 +866,19 @@
       (pop gnus-agent-group-alist))))
 
 (defun gnus-agent-fetch-headers (group &optional force)
-  (let ((articles (gnus-list-of-unread-articles group))
+  (let ((articles (gnus-uncompress-range (gnus-active group)))
 	(gnus-decode-encoded-word-function 'identity)
 	(file (gnus-agent-article-name ".overview" group)))
-    ;; Add article with marks to list of article headers we want to fetch.
-    (dolist (arts (gnus-info-marks (gnus-get-info group)))
-      (setq articles (union (gnus-uncompress-sequence (cdr arts))
-			    articles)))
-    (setq articles (sort articles '<))
+    (gnus-agent-load-alist gnus-newsgroup-name)
     ;; Remove known articles.
-    (when (gnus-agent-load-alist group)
-      (setq articles (gnus-sorted-intersection
-		      articles
-		      (gnus-uncompress-range
-		       (cons (1+ (caar (last gnus-agent-article-alist)))
-			     (cdr (gnus-active group)))))))
+    (while (and articles
+		(cdr (assq (car articles) gnus-agent-article-alist)))
+      (pop articles))
+    (let ((arts articles))
+      (while (cdr arts)
+	(if (assq (cadr arts) gnus-agent-article-alist)
+	    (setcdr arts (cddr arts))
+	  (setq arts (cdr arts)))))
     ;; Fetch them.
     (gnus-make-directory (nnheader-translate-file-chars
 			  (file-name-directory file) t))
@@ -1267,7 +1264,7 @@
   (setq gnus-category-alist
 	(or (gnus-agent-read-file
 	     (nnheader-concat gnus-agent-directory "lib/categories"))
-	    (list (list 'default 'short nil nil)))))
+	    (list (list 'default '(and short (not read)) nil nil)))))
 
 (defun gnus-category-write ()
   "Write the category alist."
@@ -1360,6 +1357,7 @@
     (long . gnus-agent-long-p)
     (low . gnus-agent-low-scored-p)
     (high . gnus-agent-high-scored-p)
+    (read . gnus-agent-read-p)
     (true . gnus-agent-true)
     (false . gnus-agent-false))
   "Mapping from short score predicate symbols to predicate functions.")
@@ -1390,6 +1388,11 @@
 (defun gnus-agent-high-scored-p ()
   "Say whether an article has a high score or not."
   (> gnus-score gnus-agent-high-score))
+
+(defun gnus-agent-read-p ()
+  "Say whether an article is read or not."
+  (gnus-member-of-range (mail-header-number gnus-headers)
+			(gnus-info-read (gnus-get-info gnus-newsgroup-name))))
 
 (defun gnus-category-make-function (cat)
   "Make a function from category CAT."
Index: lisp/gnus-sum.el
===================================================================
RCS file: /usr/local/cvsroot/gnus/lisp/gnus-sum.el,v
retrieving revision 5.122
diff -w -u -r5.122 gnus-sum.el
--- lisp/gnus-sum.el	2000/06/16 23:13:10	5.122
+++ lisp/gnus-sum.el	2000/06/30 18:22:28
@@ -4416,9 +4416,14 @@
        
 	(when (gnus-check-backend-function
 	       'request-set-mark gnus-newsgroup-name)
+	  ;; propagate flags to server, with the following exceptions:
 	  ;; uncompressed:s are not proper flags (they are cons cells)
 	  ;; cache is a internal gnus flag
-	  (unless (memq (cdr type) (cons 'cache uncompressed))
+	  ;; download are local to one gnus installation (well)
+	  ;; unsend are for nndraft groups only
+	  ;; xxx: generality of this?  this suits nnimap anyway
+	  (unless (memq (cdr type) (append '(cache download unsend)
+					   uncompressed))
 	    (let* ((old (cdr (assq (cdr type) (gnus-info-marks info))))
 		   (del (gnus-remove-from-range (gnus-copy-sequence old) list))
 		   (add (gnus-remove-from-range
Index: texi/gnus.texi
===================================================================
RCS file: /usr/local/cvsroot/gnus/texi/gnus.texi,v
retrieving revision 5.177
diff -w -u -r5.177 gnus.texi
--- texi/gnus.texi	2000/06/27 13:16:20	5.177
+++ texi/gnus.texi	2000/06/30 18:22:32
@@ -14157,8 +14157,7 @@
 
 Perhaps some examples are in order.
 
-Here's a simple predicate.  (It's the default predicate, in fact, used
-for all groups that don't belong to any other category.)
+Here's a simple predicate.
 
 @lisp
 short
@@ -14180,6 +14179,15 @@
 or if the score is not low and the article is not long.  You get the
 drift.
 
+The following predicate is the default, and is used for all groups
+that don't belong to any other category.  It downloads short unread
+articles.
+
+@lisp
+(and short
+     (not read))
+@end lisp
+
 The available logical operators are @code{or}, @code{and} and
 @code{not}.  (If you prefer, you can use the more ``C''-ish operators
 @samp{|}, @code{&} and @code{!} instead.)
@@ -14209,6 +14217,9 @@
 heuristics may change over time, but at present it just computes a
 checksum and sees whether articles match.
 
+@item read
+True iff the article is marked as read.
+
 @item true
 Always true.
 
@@ -14271,9 +14282,14 @@
 (agent-predicate . short)
 @end lisp
 
-This is the group parameter equivalent of the agent category default.
 Note that when specifying a single word predicate like this, the
 @code{agent-predicate} specification must be in dotted pair notation.
+
+This is the group parameter equivalent of the agent category default.
+
+@lisp
+(agent-predicate and short (not read))
+@end lisp
 
 The equivalent of the longer example from above would be:
 




^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [patch] gnus agent
  2000-07-01 18:24 [patch] gnus agent Simon Josefsson
@ 2000-07-01 19:25 ` Harry Putnam
  2000-07-02  3:49   ` John Prevost
  2000-07-03  8:43   ` Simon Josefsson
  2000-08-08 19:06 ` Christoph Rohland
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 10+ messages in thread
From: Harry Putnam @ 2000-07-01 19:25 UTC (permalink / raw)


Simon Josefsson <simon@josefsson.org> writes:

> This patch make all articles eligible for agent download, filtered
> only by predicates, instead of the hardcoded algorithm that choses
> what to download from unread articles only.
> 
> Any agent users that care to verify that this doesn't break anything?

I'd like to try this out but I'm not real clear what to expect.  What
does this mean in practice?  (`filtered only by predicates') No agent
score involved?  Still requires marking with % if read? 




^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [patch] gnus agent
  2000-07-01 19:25 ` Harry Putnam
@ 2000-07-02  3:49   ` John Prevost
  2000-07-03  8:43   ` Simon Josefsson
  1 sibling, 0 replies; 10+ messages in thread
From: John Prevost @ 2000-07-02  3:49 UTC (permalink / raw)
  Cc: ding

>>>>> "hp" == Harry Putnam <reader@newsguy.com> writes:

    hp> I'd like to try this out but I'm not real clear what to
    hp> expect.  What does this mean in practice?  (`filtered only by
    hp> predicates') No agent score involved?  Still requires marking
    hp> with % if read?

The impression I get is that it will read read as well as unread
messages--a bonus for me, since I have a laptop and would like to be
able to download all messages to my laptop when I'm away, but read
on-line when I'm local.

With the old behavior, if I forgot to plug, get news, and unplug, then
those messages I read would never be able to appear in my agent ever
again.  Not a good thing, next time I'm halfway to work on the bus and
need to read such an old email.

I'm very glad to see this patch.  :)

John.





^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [patch] gnus agent
  2000-07-01 19:25 ` Harry Putnam
  2000-07-02  3:49   ` John Prevost
@ 2000-07-03  8:43   ` Simon Josefsson
  1 sibling, 0 replies; 10+ messages in thread
From: Simon Josefsson @ 2000-07-03  8:43 UTC (permalink / raw)
  Cc: ding

Harry Putnam <reader@newsguy.com> writes:

> I'd like to try this out but I'm not real clear what to expect.
> What does this mean in practice?  (`filtered only by predicates') No
> agent score involved?  Still requires marking with % if read?

The patch does two things:

. Make sure all articles are eligible for agent download, see below.

. Introduce a new predicate `read' to match read mail.  Replacing your
current Agent predicates with

        (and (not read)
                <yourearlierpredicate>)

should make things the same as it was before.  The default predicate
has been changed, so if you didn't define any categories, there should
be no change at all (except for new features).

I'm not sure this should be commited to Gnus 5.8 since it alter the
current behaviour, even though it make it consistent with
documentation.  The current `bug' is probably more of a `feature', I
think.

The documentation for categories below, note the "...every available
articles...".  Earlier this just wasn't true, only UNREAD articles
(having article numbers larger than the highest already downloaded
article) was eligible for agent scoring/predicate rules.

Category Syntax
...............

   A category consists of two things.

  1. A predicate which (generally) gives a rough outline of which
     articles are eligible for downloading; and

  2. a score rule which (generally) gives you a finer granularity when
     deciding what articles to download.  (Note that this "download
     score" is not necessarily related to normal scores.)

   A predicate in its simplest form can be a single predicate such as
`true' or `false'.  These two will download every available article or
nothing respectively.  In the case of these two special predicates an
additional score rule is superfluous.




^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [patch] gnus agent
  2000-07-01 18:24 [patch] gnus agent Simon Josefsson
  2000-07-01 19:25 ` Harry Putnam
@ 2000-08-08 19:06 ` Christoph Rohland
  2000-08-10 11:03 ` Christoph Rohland
  2000-08-14 18:45 ` Lars Magne Ingebrigtsen
  3 siblings, 0 replies; 10+ messages in thread
From: Christoph Rohland @ 2000-08-08 19:06 UTC (permalink / raw)
  Cc: ding

Simon Josefsson <simon@josefsson.org> writes:

> This patch make all articles eligible for agent download, filtered
> only by predicates, instead of the hardcoded algorithm that choses
> what to download from unread articles only.
> 
> Any agent users that care to verify that this doesn't break anything?

I tried this patch and it looks quite nice and like what I always
wanted to have. But if I e.g. use the predicate 'true' or also (or
(not read) (and read short)) to fetch (mostly) all articles in a
Group, I always get

Error ((end-of-file  *Gnus agent overview*)).

on the second fetch. And the agent becomes unuseable.

Greetings
		Christoph

-- 



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [patch] gnus agent
  2000-07-01 18:24 [patch] gnus agent Simon Josefsson
  2000-07-01 19:25 ` Harry Putnam
  2000-08-08 19:06 ` Christoph Rohland
@ 2000-08-10 11:03 ` Christoph Rohland
  2000-08-10 12:44   ` simon
  2000-08-14 18:45 ` Lars Magne Ingebrigtsen
  3 siblings, 1 reply; 10+ messages in thread
From: Christoph Rohland @ 2000-08-10 11:03 UTC (permalink / raw)
  Cc: ding

Simon Josefsson <simon@josefsson.org> writes:

> This patch make all articles eligible for agent download, filtered
> only by predicates, instead of the hardcoded algorithm that choses
> what to download from unread articles only.
> 
> Any agent users that care to verify that this doesn't break anything?

Another side effect of this patch: You always loose your readedness
information when using this with nnimap. It apparently refreshes this
info from the imap server, but never pushes the local information
upstream. So I finally reverted the patch from my setup.

Greetings
		Christoph



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [patch] gnus agent
  2000-08-10 11:03 ` Christoph Rohland
@ 2000-08-10 12:44   ` simon
  2000-08-10 13:17     ` Christoph Rohland
  0 siblings, 1 reply; 10+ messages in thread
From: simon @ 2000-08-10 12:44 UTC (permalink / raw)
  Cc: ding

Christoph Rohland <cr@sap.com> writes:

> > This patch make all articles eligible for agent download, filtered
> > only by predicates, instead of the hardcoded algorithm that choses
> > what to download from unread articles only.
> > 
> > Any agent users that care to verify that this doesn't break anything?
> 
> Another side effect of this patch: You always loose your readedness
> information when using this with nnimap. It apparently refreshes this
> info from the imap server, but never pushes the local information
> upstream. So I finally reverted the patch from my setup.

You can push flags upstream with `J Y'.




^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [patch] gnus agent
  2000-08-10 12:44   ` simon
@ 2000-08-10 13:17     ` Christoph Rohland
  0 siblings, 0 replies; 10+ messages in thread
From: Christoph Rohland @ 2000-08-10 13:17 UTC (permalink / raw)


simon@josefsson.org writes:

> Christoph Rohland <cr@sap.com> writes:
>
> > Another side effect of this patch: You always loose your readedness
> > information when using this with nnimap. It apparently refreshes this
> > info from the imap server, but never pushes the local information
> > upstream. So I finally reverted the patch from my setup.
> 
> You can push flags upstream with `J Y'.

Oh great, thanks for the hint!

Greetings
		Christoph



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [patch] gnus agent
  2000-07-01 18:24 [patch] gnus agent Simon Josefsson
                   ` (2 preceding siblings ...)
  2000-08-10 11:03 ` Christoph Rohland
@ 2000-08-14 18:45 ` Lars Magne Ingebrigtsen
  2000-08-14 19:48   ` simon
  3 siblings, 1 reply; 10+ messages in thread
From: Lars Magne Ingebrigtsen @ 2000-08-14 18:45 UTC (permalink / raw)


Simon Josefsson <simon@josefsson.org> writes:

> This patch make all articles eligible for agent download, filtered
> only by predicates, instead of the hardcoded algorithm that choses
> what to download from unread articles only.

Sounds like a good idea.  Please do apply.

-- 
(domestic pets only, the antidote for overdose, milk.)
   larsi@gnus.org * Lars Magne Ingebrigtsen



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [patch] gnus agent
  2000-08-14 18:45 ` Lars Magne Ingebrigtsen
@ 2000-08-14 19:48   ` simon
  0 siblings, 0 replies; 10+ messages in thread
From: simon @ 2000-08-14 19:48 UTC (permalink / raw)


Lars Magne Ingebrigtsen <larsi@gnus.org> writes:

> > This patch make all articles eligible for agent download, filtered
> > only by predicates, instead of the hardcoded algorithm that choses
> > what to download from unread articles only.
> 
> Sounds like a good idea.  Please do apply.

It does have one problem though -- people that have configured agent
predicates will have to revise them to get the "old" behaviour, since
the patch make the default change.  They would need to add `(and (not
read) ...)' to get the same semantics.  I'm not sure anyone would
notice and/or care, but it is a change.  (That's why I'm not sure it's
good for the 5.8 series.)

And changing predicates in existing Agent groups is troublesome --
articles that was rejected by the earlier predicate are NOT eligible
for the new predicate.  One have to manually remove the Agent cache.

Many moons ago, I added a patch to solve that. It made the Agent look
at ALL articles every time you synched the Agent ('J s') but it was
taken out because it was simply too slow.

There's a better solution though -- making Agent store what predicates
is used when you synch the Agent and compare it the next time.  If the
predicate has changed, it clears the .agentview file.  This makes the
Agent go through ALL headers in the group, re-running the predicate on
all articles.

Since this would provoke a massive re-download of lots of articles
too, modifying the Agent to see if article X exist locally before
fetching it became necessery.

The following patch implement that. (It's against CVS, so it includes
the previous patch which I didn't commit yet) In addition, it does the
following too:

.  postpones unplugged GCC's until you're plugged (so you can Gcc into
   a nnimap group, for example).

.  query the user at plugin-time if she want to synchronize flags
   (user customizable by `gnus-agent-synchronize-flags'). It only happens
   if the user actually modified remote flags, so it doesn't affect nntp
   users.

.  makes the agent somewhat more verbose

Um, whad'ya'think?

2000-08-05  Simon Josefsson <simon@josefsson.org>

        Make GCC to nnimap group work when disconnected.

        * gnus-draft.el (gnus-draft-send): Call `gnus-agent-restore-gcc'.

        * gnus-agent.el (gnus-agent-possibly-do-gcc): 
        (gnus-agent-restore-gcc): 
        (gnus-agent-possibly-save-gcc): New functions.

        * gnus-msg.el (gnus-inews-add-send-actions): Use
        `gnus-agent-possibly-do-gcc' if Agentized.
        (gnus-inews-add-send-actions): Add `gnus-agent-possibly-save-gcc'
        to `message-header-hook'.

        * gnus.el (gnus-agent-gcc-header): New variable.

2000-07-13  Simon Josefsson <simon@josefsson.org>

        Asks the user to synch flags with server when you plug in.

        * gnus-agent.el (gnus-agent-synchronize-flags): New variable.
        (gnus-agent-possibly-synchronize-flags-server): New function, use it.
        (gnus-agent-toggle-plugged): Call it.
        (gnus-agent-synchronize-flags): Renamed from `gnus-agent-synchronize'.
        (gnus-agent-group-mode-map): `g-a-s' -> `g-a-s-flags'.
        (gnus-agent-possibly-synchronize-flags): New function.
        (gnus-agent-possibly-synchronize-flags-server): New function.

2000-07-13  Simon Josefsson <simon@josefsson.org>

        Changing predicates for a group re-sync Gnus status on the
        group.

        * gnus-agent.el (gnus-agent-fetch-group-1): Clean agent overview
        if predicates chanted.
        (gnus-agent-load-predicate): New function.
        (gnus-agent-write-predicate): Ditto.

Index: gnus-agent.el
===================================================================
RCS file: /usr/local/cvsroot/gnus/lisp/gnus-agent.el,v
retrieving revision 5.55
diff -w -u -r5.55 gnus-agent.el
--- gnus-agent.el	2000/07/13 17:19:05	5.55
+++ gnus-agent.el	2000/08/14 19:33:13
@@ -83,6 +83,14 @@
   :group 'gnus-agent
   :type 'function)
 
+(defcustom gnus-agent-synchronize-flags 'ask
+  "Indicate if flags are synchronized when you plug in.
+If this is `ask' the hook will query the user."
+  :type '(choice (const :tag "Always" t)
+		 (const :tag "Never" nil)
+		 (const :tag "Ask" ask))
+  :group 'gnus-agent)
+
 ;;; Internal variables
 
 (defvar gnus-agent-history-buffers nil)
@@ -233,7 +241,7 @@
   "Jc" gnus-enter-category-buffer
   "Jj" gnus-agent-toggle-plugged
   "Js" gnus-agent-fetch-session
-  "JY" gnus-agent-synchronize
+  "JY" gnus-agent-synchronize-flags
   "JS" gnus-group-send-drafts
   "Ja" gnus-agent-add-group
   "Jr" gnus-agent-remove-group)
@@ -290,6 +298,7 @@
   (if plugged
       (progn
 	(setq gnus-plugged plugged)
+	(gnus-agent-possibly-synchronize-flags)
 	(gnus-run-hooks 'gnus-agent-plugged-hook)
 	(setcar (cdr gnus-agent-mode-status) " Plugged"))
     (gnus-agent-close-connections)
@@ -371,6 +380,27 @@
     (while (search-backward "\n" nil t)
       (replace-match "\\n" t t))))
 
+(defun gnus-agent-restore-gcc ()
+  "Restore GCC field from saved header."
+  (save-excursion
+    (goto-char (point-min))
+    (while (re-search-forward (concat gnus-agent-gcc-header ":") nil t)
+      (replace-match "Gcc:" 'fixedcase))))
+  
+(defun gnus-agent-possibly-save-gcc ()
+  "Save GCC if Gnus is unplugged."
+  (unless gnus-plugged
+    (save-excursion
+      (goto-char (point-min))
+      (let ((case-fold-search t))
+	(while (re-search-forward "^gcc:" nil t)
+	  (replace-match (concat gnus-agent-gcc-header ":") 'fixedcase))))))
+
+(defun gnus-agent-possibly-do-gcc ()
+  "Do GCC if Gnus is plugged."
+  (when gnus-plugged
+    (gnus-inews-do-gcc)))
+
 ;;;
 ;;; Group mode commands
 ;;;
@@ -425,13 +455,26 @@
 	  (setf (cadddr c) (delete group (cadddr c))))))
     (gnus-category-write)))
 
-(defun gnus-agent-synchronize ()
-  "Synchronize local, unplugged, data with backend.
-Currently sends flag setting requests, if any."
+(defun gnus-agent-synchronize-flags ()
+  "Synchronize unplugged flags with servers."
   (interactive)
   (save-excursion
     (dolist (gnus-command-method gnus-agent-covered-methods)
       (when (file-exists-p (gnus-agent-lib-file "flags"))
+	(gnus-agent-synchronize-flags-server gnus-command-method)))))
+
+(defun gnus-agent-possibly-synchronize-flags ()
+  "Synchronize flags according to `gnus-agent-synchronize-flags'."
+  (interactive)
+  (save-excursion
+    (dolist (gnus-command-method gnus-agent-covered-methods)
+      (when (file-exists-p (gnus-agent-lib-file "flags"))
+	(gnus-agent-possibly-synchronize-flags-server gnus-command-method)))))
+
+(defun gnus-agent-synchronize-flags-server (method)
+  "Synchronize flags set when unplugged for server."
+  (let ((gnus-command-method method))
+    (when (file-exists-p (gnus-agent-lib-file "flags"))
 	(set-buffer (get-buffer-create " *Gnus Agent flag synchronize*"))
 	(erase-buffer)
 	(nnheader-insert-file-contents (gnus-agent-lib-file "flags"))
@@ -444,8 +487,17 @@
 	      (write-file (gnus-agent-lib-file "flags"))
 	      (error "Couldn't set flags from file %s"
 		     (gnus-agent-lib-file "flags"))))
-	  (write-file (gnus-agent-lib-file "flags")))
-        (kill-buffer nil)))))
+	(delete-file (gnus-agent-lib-file "flags")))
+      (kill-buffer nil))))
+
+(defun gnus-agent-possibly-synchronize-flags-server (method)
+  "Synchronize flags for server according to `gnus-agent-synchronize-flags'."
+  (when (or (and gnus-agent-synchronize-flags
+		 (not (eq gnus-agent-synchronize-flags 'ask)))
+	    (and (eq gnus-agent-synchronize-flags 'ask)
+		 (gnus-y-or-n-p (format "Synchronize flags on server `%s'? " 
+					(cadr method)))))
+    (gnus-agent-synchronize-flags-server method)))
 
 ;;;
 ;;; Server mode commands
@@ -553,9 +605,8 @@
 	       (gnus-agent-method-p gnus-command-method))
       (gnus-agent-load-alist gnus-newsgroup-name)
       ;; First mark all undownloaded articles as undownloaded.
-      (let ((articles (append gnus-newsgroup-unreads
-			      gnus-newsgroup-marked
-			      gnus-newsgroup-dormant))
+      (let ((articles (gnus-uncompress-sequence 
+		       (gnus-active gnus-newsgroup-name)))
 	    article)
 	(while (setq article (pop articles))
 	  (unless (or (cdr (assq article gnus-agent-article-alist))
@@ -752,25 +803,37 @@
 
 (defun gnus-agent-fetch-articles (group articles)
   "Fetch ARTICLES from GROUP and put them into the Agent."
-  (when articles
-    ;; Prune off articles that we have already fetched.
+  (let ((dir (concat (gnus-agent-directory) (gnus-agent-group-path group) "/"))
+	(date (time-to-days (current-time)))
+	(case-fold-search t)
+	pos crosses id elem exist)
+    ;; Prune off articles that we have already fetched, and notice
+    ;; articles that (for some reason) already exist locally.
     (while (and articles
-		(cdr (assq (car articles) gnus-agent-article-alist)))
+		(or (cdr (assq (car articles) gnus-agent-article-alist))
+		    (setq exist (file-readable-p
+				 (expand-file-name
+				  (int-to-string (car articles)) dir)))))
+      (when exist
+	(setcdr (assq (car articles) gnus-agent-article-alist) t)
+	(setq exist nil))
       (pop articles))
     (let ((arts articles))
       (while (cdr arts)
-	(if (cdr (assq (cadr arts) gnus-agent-article-alist))
-	    (setcdr arts (cddr arts))
+	(if (or (cdr (assq (cadr arts) gnus-agent-article-alist))
+		(setq exist (file-readable-p
+			     (expand-file-name
+			      (int-to-string (cadr arts)) dir))))
+	    (progn
+	      (when exist
+		(setcdr (assq (cadr arts) gnus-agent-article-alist) t)
+		(setq exist nil))
+	      (setcdr arts (cddr arts)))
 	  (setq arts (cdr arts)))))
     (when articles
-      (let ((dir (concat
-		  (gnus-agent-directory)
-		  (gnus-agent-group-path group) "/"))
-	    (date (time-to-days (current-time)))
-	    (case-fold-search t)
-	    pos crosses id elem)
 	(gnus-make-directory dir)
-	(gnus-message 7 "Fetching articles for %s..." group)
+      (gnus-message 7 "Fetching articles %s for %s..." 
+		    (gnus-compress-sequence articles) group)
 	;; Fetch the articles from the backend.
 	(if (gnus-check-backend-function 'retrieve-articles group)
 	    (setq pos (gnus-retrieve-articles articles group))
@@ -820,8 +883,8 @@
 	    (gnus-agent-enter-history
 	     id (or crosses (list (cons group (caar pos)))) date)
 	    (widen)
-	    (pop pos)))
-	(gnus-agent-save-alist group)))))
+	  (pop pos))))
+    (gnus-agent-save-alist group)))
 
 (defun gnus-agent-crosspost (crosses article)
   (let (gnus-agent-article-alist group alist beg end)
@@ -868,14 +931,9 @@
       (pop gnus-agent-group-alist))))
 
 (defun gnus-agent-fetch-headers (group &optional force)
-  (let ((articles (gnus-list-of-unread-articles group))
+  (let ((articles (gnus-uncompress-range (gnus-active group)))
 	(gnus-decode-encoded-word-function 'identity)
 	(file (gnus-agent-article-name ".overview" group)))
-    ;; Add article with marks to list of article headers we want to fetch.
-    (dolist (arts (gnus-info-marks (gnus-get-info group)))
-      (setq articles (union (gnus-uncompress-sequence (cdr arts))
-			    articles)))
-    (setq articles (sort articles '<))
     ;; Remove known articles.
     (when (gnus-agent-load-alist group)
       (setq articles (gnus-sorted-intersection
@@ -935,8 +993,8 @@
 	(goto-char (point-max))
 	(insert-buffer-substring gnus-agent-overview-buffer))
     ;; We do it the hard way.
-    (nnheader-find-nov-line (car articles))
-    (gnus-agent-copy-nov-line (car articles))
+    (and (nnheader-find-nov-line (car articles))
+	 (gnus-agent-copy-nov-line (car articles)))
     (pop articles)
     (while (and articles
 		(not (eobp)))
@@ -955,6 +1013,19 @@
 	(set-buffer nntp-server-buffer)
 	(insert-buffer-substring gnus-agent-overview-buffer b e)))))
 
+(defun gnus-agent-load-predicate (group)
+  "Return the predicate used to generate .agentview file for GROUP."
+  (gnus-agent-read-file (gnus-agent-article-name ".predicate" group)))
+
+(defun gnus-agent-write-predicate (group predicate)
+  "Write the predicate used to generate .agentview file for GROUP."
+  (let ((file-name-coding-system nnmail-pathname-coding-system)
+	(file (gnus-agent-article-name ".predicate" group)))
+    (gnus-make-directory (file-name-directory file))
+    (with-temp-file file
+      (princ predicate (current-buffer))
+      (insert "\n"))))
+
 (defun gnus-agent-load-alist (group &optional dir)
   "Load the article-state alist for GROUP."
   (setq gnus-agent-article-alist
@@ -965,10 +1036,12 @@
 
 (defun gnus-agent-save-alist (group &optional articles state dir)
   "Save the article-state alist for GROUP."
-  (let ((file-name-coding-system nnmail-pathname-coding-system))
-      (with-temp-file (if dir
+  (let ((file-name-coding-system nnmail-pathname-coding-system)
+	(file (if dir
 			  (concat dir ".agentview")
-			(gnus-agent-article-name ".agentview" group))
+		(gnus-agent-article-name ".agentview" group))))
+    (gnus-make-directory (file-name-directory file))
+    (with-temp-file file
 	(princ (setq gnus-agent-article-alist
 		     (nconc gnus-agent-article-alist
 			    (mapcar (lambda (article) (cons article state))
@@ -1036,8 +1109,21 @@
 	;; Maybe some other gnus-summary local variables should also
 	;; be put here.
 	)
+    (gnus-message 9 "Agent fetching group %s..." group)
     (unless (gnus-check-group group)
       (error "Can't open server for %s" group))
+    ;; Check if predicates have changed
+    (setq category (gnus-group-category group))
+    (setq predicate
+	  (gnus-get-predicate
+	   (or (gnus-group-find-parameter group 'agent-predicate t)
+	       (cadr category))))
+    (unless (equal predicate (gnus-agent-load-predicate group))
+      (when (gnus-agent-load-alist group)
+	(gnus-message 5 "Agent predicate change detected for %s..." group))
+      (let (gnus-agent-article-alist)
+	(gnus-agent-save-alist group))
+      (gnus-agent-write-predicate group predicate))
     ;; Fetch headers.
     (when (and (or (gnus-active group) (gnus-activate-group group))
 	       (setq articles (gnus-agent-fetch-headers group))
@@ -1055,11 +1141,8 @@
 		 ;; `gnus-agent-overview-buffer' may be killed for
 		 ;; timeout reason.  If so, recreate it.
 		 (gnus-agent-create-buffer)))
-      (setq category (gnus-group-category group))
-      (setq predicate
-	    (gnus-get-predicate
-	     (or (gnus-group-find-parameter group 'agent-predicate t)
-		 (cadr category))))
+      (gnus-message 8 "Agent looking in %s at articles %s..."
+		    group (gnus-compress-sequence articles))
       ;; Do we want to download everything, or nothing?
       (if (or (eq (caaddr predicate) 'gnus-agent-true)
 	      (eq (caaddr predicate) 'gnus-agent-false))
@@ -1097,6 +1180,7 @@
 			score-method
 		      (list (list score-method)))))))
 	(when score-param
+	  (gnus-message 8 "Agent scores in group %s..." group)
 	  (gnus-score-headers score-param))
 	(setq arts nil)
 	(while (setq gnus-headers (pop gnus-newsgroup-headers))
@@ -1104,16 +1188,20 @@
 		(or (cdr (assq (mail-header-number gnus-headers)
 			       gnus-newsgroup-scored))
 		    gnus-summary-default-score))
-	  (when (funcall predicate)
-	    (push (mail-header-number gnus-headers)
-		  arts))))
+	  (if (funcall predicate)
+	      (push (mail-header-number gnus-headers) arts))))
+      (gnus-message 8 "Agent predicate accepted %s..."
+		    (gnus-compress-sequence arts)))
       ;; Fetch the articles.
       (when arts
-	(gnus-agent-fetch-articles group arts)))
+      (gnus-message 8 "Agent fetching articles %s..."
+		    (gnus-compress-sequence arts))
+      (gnus-agent-fetch-articles group arts))
     ;; Perhaps we have some additional articles to fetch.
     (setq arts (assq 'download (gnus-info-marks
 				(setq info (gnus-get-info group)))))
     (when (cdr arts)
+      (gnus-message 8 "Agent is downloading marked articles...")
       (gnus-agent-fetch-articles
        group (gnus-uncompress-range (cdr arts)))
       (setq marks (delq arts (gnus-info-marks info)))
@@ -1274,7 +1362,7 @@
   (setq gnus-category-alist
 	(or (gnus-agent-read-file
 	     (nnheader-concat gnus-agent-directory "lib/categories"))
-	    (list (list 'default 'short nil nil)))))
+	    (list (list 'default '(and short (not read)) nil nil)))))
 
 (defun gnus-category-write ()
   "Write the category alist."
@@ -1367,6 +1455,7 @@
     (long . gnus-agent-long-p)
     (low . gnus-agent-low-scored-p)
     (high . gnus-agent-high-scored-p)
+    (read . gnus-agent-read-p)
     (true . gnus-agent-true)
     (false . gnus-agent-false))
   "Mapping from short score predicate symbols to predicate functions.")
@@ -1397,6 +1486,11 @@
 (defun gnus-agent-high-scored-p ()
   "Say whether an article has a high score or not."
   (> gnus-score gnus-agent-high-score))
+
+(defun gnus-agent-read-p ()
+  "Say whether an article is read or not."
+  (gnus-member-of-range (mail-header-number gnus-headers)
+			(gnus-info-read (gnus-get-info gnus-newsgroup-name))))
 
 (defun gnus-category-make-function (cat)
   "Make a function from category CAT."
diff -w -u -r5.18 gnus-draft.el
--- lisp/gnus-draft.el  2000/04/26 16:31:37     5.18
+++ lisp/gnus-draft.el  2000/08/14 19:42:09
@@ -143,6 +143,8 @@
        (setq type (ignore-errors (read (current-buffer)))
              method (ignore-errors (read (current-buffer))))
        (message-remove-header gnus-agent-meta-information-header)))
+    ;; Let Agent restore any GCC lines and h ave message perform them.
+    (gnus-agent-restore-gcc)
     ;; Then we send it.  If we have no meta-information, we just send
     ;; it and let Message figure out how.
     (when (and (or (null method)
diff -w -u -r5.66 gnus-msg.el
--- lisp/gnus-msg.el    2000/06/25 16:49:30     5.66
+++ lisp/gnus-msg.el    2000/08/14 19:42:11
@@ -262,7 +262,11 @@
 
 (defun gnus-inews-add-send-actions (winconf buffer article)
   (make-local-hook 'message-sent-hook)
-  (add-hook 'message-sent-hook 'gnus-inews-do-gcc nil t)
+  (add-hook 'message-sent-hook (if gnus-agent 'gnus-agent-possibly-do-gcc
+                                'gnus-inews-do-gcc) nil t)
+  (when gnus-agent
+    (make-local-hook 'message-header-hook)
+    (add-hook 'message-header-hook 'gnus-agent-possibly-save-gcc nil t))
   (setq message-post-method
        `(lambda (arg)
           (gnus-post-method arg ,gnus-newsgroup-name)))
diff -w -u -r5.141 gnus.el
--- lisp/gnus.el        2000/07/13 23:11:45     5.141
+++ lisp/gnus.el        2000/08/14 19:42:16
@@ -1478,6 +1478,7 @@
 ;;; Internal variables
 
 (defvar gnus-agent-meta-information-header "X-Gnus-Agent-Meta-Information")
+(defvar gnus-agent-gcc-header "X-Gnus-Agent-Gcc")
 (defvar gnus-group-get-parameter-function 'gnus-group-get-parameter)
 (defvar gnus-original-article-buffer " *Original Article*")
 (defvar gnus-newsgroup-name nil)




^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2000-08-14 19:48 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-07-01 18:24 [patch] gnus agent Simon Josefsson
2000-07-01 19:25 ` Harry Putnam
2000-07-02  3:49   ` John Prevost
2000-07-03  8:43   ` Simon Josefsson
2000-08-08 19:06 ` Christoph Rohland
2000-08-10 11:03 ` Christoph Rohland
2000-08-10 12:44   ` simon
2000-08-10 13:17     ` Christoph Rohland
2000-08-14 18:45 ` Lars Magne Ingebrigtsen
2000-08-14 19:48   ` simon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).