From 3d80c51c5557f5611efecf3bafa8b415c339ba05 Mon Sep 17 00:00:00 2001 From: Lars Magne Ingebrigtsen Date: Tue, 4 Mar 1997 08:54:16 +0000 Subject: [PATCH] *** empty log message *** --- lisp/ChangeLog | 30 +++ lisp/gnus-cache.el | 24 ++- lisp/gnus-gl.el | 139 +++++++------ lisp/gnus-nocem.el | 7 +- lisp/gnus-xmas.el | 2 +- lisp/gnus.el | 14 +- lisp/message.el | 50 +++-- lisp/nnvirtual.el | 3 + texi/ChangeLog | 9 + texi/gnus.texi | 484 ++++++++++++++++++++++++++++----------------- 10 files changed, 471 insertions(+), 291 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 441edd6a4..aaa0c29b6 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,33 @@ +Wed Apr 10 00:25:17 1996 Lars Magne Ingebrigtsen + + * nnvirtual.el (nnvirtual-close-group): Nix out variables. + + * gnus-cache.el (gnus-cache-possibly-remove-article): Didn't work + in virtual groups. + (gnus-cache-possibly-enter-article): Ditto. + + * message.el (message-do-fcc): Remove separator. + + * gnus-nocem.el (gnus-nocem-scan-groups): Use own dependencies + hash table. + +Tue Apr 9 23:37:36 1996 Brad Miller + + * gnus-gl.el: New version. + +Tue Apr 9 23:08:20 1996 Lars Magne Ingebrigtsen + + * gnus.el (gnus-article-de-quoted-unreadable): Downcase type. + (gnus-fetch-field): Inhibit point-motion hooks. + +Tue Apr 9 10:50:20 1996 Lars Magne Ingebrigtsen + + * message.el (message-user-mail-address): Pick out . + +Tue Apr 9 07:46:47 1996 Lars Magne Ingebrigtsen + + * gnus.el: September Gnus v0.68 is released. + Tue Apr 9 00:15:43 1996 Brad Miller * gnus-gl.el: New version. diff --git a/lisp/gnus-cache.el b/lisp/gnus-cache.el index 480815f7f..384fea13d 100644 --- a/lisp/gnus-cache.el +++ b/lisp/gnus-cache.el @@ -119,9 +119,8 @@ variable to \"^nnml\".") (let ((result (nnvirtual-find-group-art (gnus-group-real-name group) article))) (setq group (car result) - article (cdr result) headers (copy-sequence headers)) - (aset headers 0 article))) + (mail-header-set-number headers (cdr result)))) (let ((number (mail-header-number headers)) file dir) (when (and (> number 0) ; Reffed article. @@ -131,7 +130,7 @@ variable to \"^nnml\".") (gnus-cache-member-of-class gnus-cache-enter-articles ticked dormant unread)) (not (file-exists-p (setq file (gnus-cache-file-name - group article))))) + group number))))) ;; Possibly create the cache directory. (or (file-exists-p (setq dir (file-name-directory file))) (gnus-make-directory dir)) @@ -141,7 +140,7 @@ variable to \"^nnml\".") (save-excursion (set-buffer nntp-server-buffer) (let ((gnus-use-cache nil)) - (gnus-request-article-this-buffer article group)) + (gnus-request-article-this-buffer number group)) (when (> (buffer-size) 0) (write-region (point-min) (point-max) file nil 'quiet) (gnus-cache-change-buffer group) @@ -179,7 +178,7 @@ variable to \"^nnml\".") ;; Update the active info. (set-buffer gnus-summary-buffer) (gnus-cache-update-active group number) - (push number gnus-newsgroup-cached) + (push article gnus-newsgroup-cached) (gnus-summary-update-secondary-mark article)) t)))))) @@ -384,7 +383,16 @@ Returns the list of articles removed." (defun gnus-cache-possibly-remove-article (article ticked dormant unread &optional force) "Possibly remove ARTICLE from the cache." - (let ((file (gnus-cache-file-name gnus-newsgroup-name article))) + (let ((group gnus-newsgroup-name) + (number article) + file) + ;; If this is a virtual group, we find the real group. + (when (gnus-virtual-group-p group) + (let ((result (nnvirtual-find-group-art + (gnus-group-real-name group) article))) + (setq group (car result) + number (cdr result)))) + (setq file (gnus-cache-file-name group number)) (when (and (file-exists-p file) (or force (gnus-cache-member-of-class @@ -393,8 +401,8 @@ Returns the list of articles removed." (delete-file file) (set-buffer (cdr gnus-cache-buffer)) (goto-char (point-min)) - (if (or (looking-at (concat (int-to-string article) "\t")) - (search-forward (concat "\n" (int-to-string article) "\t") + (if (or (looking-at (concat (int-to-string number) "\t")) + (search-forward (concat "\n" (int-to-string number) "\t") (point-max) t)) (delete-region (progn (beginning-of-line) (point)) (progn (forward-line 1) (point))))) diff --git a/lisp/gnus-gl.el b/lisp/gnus-gl.el index a101698d7..1d4fd7cf8 100644 --- a/lisp/gnus-gl.el +++ b/lisp/gnus-gl.el @@ -120,7 +120,7 @@ ;;; Code: (require 'gnus-score) -(eval-and-compile (require 'cl)) +(require 'cl) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; User variables @@ -130,10 +130,6 @@ "%U%R%z%l%I%(%[%4L: %-20,20n%]%) %s\n" "*The line format spec in summary GroupLens mode buffers.") -(defvar gnus-summary-grouplens-lab-line-format - "%U%R%z%uL%I%(%[%4L: %-20,20n%]%) %s\n" - "*The line format spec in summary GroupLens mode buffers.") - (defvar grouplens-pseudonym "" "User's pseudonym. This pseudonym is obtained during the registration process") @@ -162,25 +158,26 @@ (defvar grouplens-score-offset 0 "Offset the prediction by this value. -Setting this variable to -2 would have the following effect on grouplens -scores: +Setting this variable to -2 would have the following effect on +GroupLens scores: + 1 --> -2 2 --> -1 3 --> 0 4 --> 1 5 --> 2 -the reason a user might want to do this is to combine grouplens -predictions with scores calculated by other score methods") +The reason is that a user might want to do this is to combine +GroupLens predictions with scores calculated by other score methods.") (defvar grouplens-score-scale-factor 1 - "This variable allow sthe user to magify the effect of grouplens scores. + "This variable allows the user to magnify the effect of GroupLens scores. The scale factor is applied after the offset.") (defvar gnus-grouplens-override-scoring t "Tell Grouplens to override the normal Gnus scoring mechanism. If this variable is non-nill than Grouplens will completely override -the normal scoring mechanism of Gnus. When nil, Grouplens will not +the normal scoring mechanism of Gnus. When nil, GroupLens will not override the normal scoring mechanism so both can be used at once.") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -212,11 +209,11 @@ override the normal scoring mechanism so both can be used at once.") (defvar bbb-alist nil) (defvar bbb-timeout-secs 10 - "Number of seconds to wait for some response from the BBB before - we give up and assume that something has died..." ) + "Number of seconds to wait for some response from the BBB. +If this times out we give up and assume that something has died..." ) (defvar grouplens-previous-article nil - "message-id of the last article read") + "Message-ID of the last article read.") (defvar bbb-read-point) (defvar bbb-response-point) @@ -352,8 +349,8 @@ recommend using both scores and grouplens predictions together." (gnus-message 3 "Error: You are not logged in to a BBB") (gnus-message 5 "Fetching Predictions...") (let (predict-list - (predict-command (build-predict-command midlist groupname - grouplens-bbb-token)) + (predict-command (bbb-build-predict-command midlist groupname + grouplens-bbb-token)) (bbb-process (bbb-connect-to-bbbd grouplens-bbb-host grouplens-bbb-port))) (if bbb-process @@ -378,7 +375,7 @@ recommend using both scores and grouplens predictions together." (setq bbb-mid-list (cons this bbb-mid-list)))) bbb-mid-list)) -(defun build-predict-command (mlist grpname token) +(defun bbb-build-predict-command (mlist grpname token) (let ((cmd (concat "getpredictions " token " " grpname "\r\n")) art) (while mlist @@ -397,13 +394,13 @@ recommend using both scores and grouplens predictions together." (goto-char bbb-read-point)) (setq match-end (point)) (goto-char (+ bbb-response-point 4)) ;; we ought to be right before OK - (build-response-alist))) + (bbb-build-response-alist))) ;; build-response-alist assumes that the cursor has been positioned at ;; the first line of the list of mid/rating pairs. For now we will ;; use a prediction of 99 to signify no prediction. Ultimately, we ;; should just ignore messages with no predictions. -(defun build-response-alist () +(defun bbb-build-response-alist () (let ((resp nil) (match-end (point))) (setq grouplens-current-hashtable (make-hash-table :test 'equal :size 100)) @@ -460,56 +457,58 @@ recommend using both scores and grouplens predictions together." (defvar gnus-tmp-score) (defun bbb-grouplens-score (header) - (let* ((rate-string (make-string 12 ? )) - (mid (aref header (nth 1 (assoc "message-id" gnus-header-index)))) - (hashent (gethash mid grouplens-current-hashtable)) - (iscore gnus-tmp-score) - (low (car (cdr hashent))) - (high (car (cdr (cdr hashent))))) - (aset rate-string 0 ?|) - (aset rate-string 11 ?|) - (unless (member grouplens-current-group grouplens-newsgroups) - (unless (equal grouplens-prediction-display 'prediction-num) - (cond ((< iscore 0) - (setq iscore 1)) - ((> iscore 5) - (setq iscore 5)))) - (setq low 0) - (setq high 0)) - (if (and (bbb-valid-score iscore) - (not (null mid))) - (cond - ;; prediction-spot - ((equal grouplens-prediction-display 'prediction-spot) - (setq rate-string (bbb-fmt-prediction-spot rate-string iscore))) - ;; confidence-interval - ((equal grouplens-prediction-display 'confidence-interval) - (setq rate-string (bbb-fmt-confidence-interval iscore low high))) - ;; prediction-bar - ((equal grouplens-prediction-display 'prediction-bar) - (setq rate-string (bbb-fmt-prediction-bar rate-string iscore))) - ;; confidence-bar - ((equal grouplens-prediction-display 'confidence-bar) - (setq rate-string (format "| %4.2f |" iscore))) - ;; confidence-spot - ((equal grouplens-prediction-display 'confidence-spot) - (setq rate-string (format "| %4.2f |" iscore))) - ;; prediction-num - ((equal grouplens-prediction-display 'prediction-num) - (setq rate-string (bbb-fmt-prediction-num iscore))) - ;; confidence-plus-minus - ((equal grouplens-prediction-display 'confidence-plus-minus) - (setq rate-string (bbb-fmt-confidence-plus-minus iscore low high)) - ) - (t (gnus-message 3 "Invalid prediction display type"))) - (aset rate-string 5 ?N) (aset rate-string 6 ?A)) - rate-string)) + (if (null gnus-grouplens-override-scoring) + (bbb-grouplens-other-score header) + (let* ((rate-string (make-string 12 ? )) + (mid (aref header (nth 1 (assoc "message-id" gnus-header-index)))) + (hashent (gethash mid grouplens-current-hashtable)) + (iscore gnus-tmp-score) + (low (car (cdr hashent))) + (high (car (cdr (cdr hashent))))) + (aset rate-string 0 ?|) + (aset rate-string 11 ?|) + (unless (member grouplens-current-group grouplens-newsgroups) + (unless (equal grouplens-prediction-display 'prediction-num) + (cond ((< iscore 0) + (setq iscore 1)) + ((> iscore 5) + (setq iscore 5)))) + (setq low 0) + (setq high 0)) + (if (and (bbb-valid-score iscore) + (not (null mid))) + (cond + ;; prediction-spot + ((equal grouplens-prediction-display 'prediction-spot) + (setq rate-string (bbb-fmt-prediction-spot rate-string iscore))) + ;; confidence-interval + ((equal grouplens-prediction-display 'confidence-interval) + (setq rate-string (bbb-fmt-confidence-interval iscore low high))) + ;; prediction-bar + ((equal grouplens-prediction-display 'prediction-bar) + (setq rate-string (bbb-fmt-prediction-bar rate-string iscore))) + ;; confidence-bar + ((equal grouplens-prediction-display 'confidence-bar) + (setq rate-string (format "| %4.2f |" iscore))) + ;; confidence-spot + ((equal grouplens-prediction-display 'confidence-spot) + (setq rate-string (format "| %4.2f |" iscore))) + ;; prediction-num + ((equal grouplens-prediction-display 'prediction-num) + (setq rate-string (bbb-fmt-prediction-num iscore))) + ;; confidence-plus-minus + ((equal grouplens-prediction-display 'confidence-plus-minus) + (setq rate-string (bbb-fmt-confidence-plus-minus iscore low high)) + ) + (t (gnus-message 3 "Invalid prediction display type"))) + (aset rate-string 5 ?N) (aset rate-string 6 ?A)) + rate-string))) ;; ;; Gnus user format function that doesn't depend on ;; bbb-build-mid-scores-alist being used as the score function, but is ;; instead called from gnus-select-group-hook. -- LAB -(defun gnus-user-format-function-L (header) +(defun bbb-grouplens-other-score (header) (if (not (member grouplens-current-group grouplens-newsgroups)) ;; Return an empty string "" @@ -621,7 +620,7 @@ recommend using both scores and grouplens predictions together." (member gnus-newsgroup-name grouplens-newsgroups)) (let ((bbb-process (bbb-connect-to-bbbd grouplens-bbb-host grouplens-bbb-port)) - (rate-command (build-rate-command grouplens-rating-alist))) + (rate-command (bbb-build-rate-command grouplens-rating-alist))) (if bbb-process (save-excursion (set-buffer (process-buffer bbb-process)) @@ -636,7 +635,7 @@ recommend using both scores and grouplens predictions together." (gnus-message 3 "No BBB connection"))) (setq grouplens-rating-alist nil))) -(defun build-rate-command (rate-alist) +(defun bbb-build-rate-command (rate-alist) (let (this (cmd (concat "putratings " grouplens-bbb-token " " grouplens-current-group " \r\n"))) @@ -752,7 +751,7 @@ recommend using both scores and grouplens predictions together." ;; BUG REPORTING ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defconst gnus-gl-version "gnus-gl.el 2.11") +(defconst gnus-gl-version "gnus-gl.el 2.12") (defconst gnus-gl-maintainer-address "grouplens-bug@cs.umn.edu") (defun gnus-gl-submit-bug-report () "Submit via mail a bug report on gnus-gl" @@ -836,10 +835,10 @@ recommend using both scores and grouplens predictions together." '(lambda() (bbb-build-mid-scores-alist gnus-newsgroup-name)))) (make-local-variable 'gnus-summary-line-format) - (if (null gnus-grouplens-override-scoring) - - (setq gnus-summary-line-format gnus-summary-grouplens-lab-line-format)) + (setq gnus-summary-line-format + gnus-summary-grouplens-line-format) (make-local-variable 'gnus-summary-line-format-spec) + (setq gnus-summary-line-format-spec nil) ;; Set up the menu. (when (and menu-bar-mode diff --git a/lisp/gnus-nocem.el b/lisp/gnus-nocem.el index a917429ef..ea8e7407b 100644 --- a/lisp/gnus-nocem.el +++ b/lisp/gnus-nocem.el @@ -90,7 +90,7 @@ ;; Ok, there are new articles in this group, se we fetch the ;; headers. (save-excursion - (let ((gnus-newsgroup-dependencies (make-vector 10 nil)) + (let ((dependencies (make-vector 10 nil)) (buffer (nnheader-set-temp-buffer " *Gnus NoCeM*")) headers) (setq headers @@ -103,8 +103,9 @@ (car gactive)) (cdr gactive)))) group)) - (gnus-get-newsgroup-headers-xover articles) - (gnus-get-newsgroup-headers))) + (gnus-get-newsgroup-headers-xover + articles nil dependencies) + (gnus-get-newsgroup-headers dependencies))) (while headers ;; We take a closer look on all articles that have ;; "@@NCM" in the subject. diff --git a/lisp/gnus-xmas.el b/lisp/gnus-xmas.el index f5a4b293f..647143ad4 100644 --- a/lisp/gnus-xmas.el +++ b/lisp/gnus-xmas.el @@ -403,7 +403,7 @@ pounce directly on the real variables themselves.") (defun gnus-xmas-redefine () "Redefine lots of Gnus functions for XEmacs." - (fset 'gnus-summary-make-display-table (lambda () nil)) + (fset 'gnus-summary-make-display-table 'ignore) (fset 'gnus-visual-turn-off-edit-menu 'identity) (fset 'gnus-highlight-selected-summary 'gnus-xmas-highlight-selected-summary) diff --git a/lisp/gnus.el b/lisp/gnus.el index fe4a74cd0..a4cc56764 100644 --- a/lisp/gnus.el +++ b/lisp/gnus.el @@ -1149,7 +1149,7 @@ with some simple extensions. %z Article zcore (character) %t Number of articles under the current thread (number). %e Whether the thread is empty or not (character). -%l GroupLens score (number) +%l GroupLens score (string). %u User defined specifier. The next character in the format string should be a letter. Gnus will call the function gnus-user-format-function-X, where X is the letter following %u. The function will be passed the @@ -1695,7 +1695,7 @@ variable (string, integer, character, etc).") "gnus-bug@ifi.uio.no (The Gnus Bugfixing Girls + Boys)" "The mail address of the Gnus maintainers.") -(defconst gnus-version "September Gnus v0.68" +(defconst gnus-version "September Gnus v0.69" "Version number for this version of Gnus.") (defvar gnus-info-nodes @@ -2421,7 +2421,8 @@ Thank you for your help in stamping out bugs. "Return the value of the header FIELD of current article." (save-excursion (save-restriction - (let ((case-fold-search t)) + (let ((case-fold-search t) + (inhibit-point-motion-hooks t)) (nnheader-narrow-to-headers) (mail-fetch-field field))))) @@ -9127,14 +9128,15 @@ The resulting hash table is returned, or nil if no Xrefs were found." '(buffer-substring (point) (if (gnus-nov-skip-field) (1- (point)) eol))) ;; Goes through the xover lines and returns a list of vectors -(defun gnus-get-newsgroup-headers-xover (sequence &optional force-new) +(defun gnus-get-newsgroup-headers-xover (sequence &optional + force-new dependencies) "Parse the news overview data in the server buffer, and return a list of headers that match SEQUENCE (see `nntp-retrieve-headers')." ;; Get the Xref when the users reads the articles since most/some ;; NNTP servers do not include Xrefs when using XOVER. (setq gnus-article-internal-prepare-hook '(gnus-article-get-xrefs)) (let ((cur nntp-server-buffer) - (dependencies gnus-newsgroup-dependencies) + (dependencies (or dependencies gnus-newsgroup-dependencies)) number headers header) (save-excursion (set-buffer nntp-server-buffer) @@ -13877,7 +13879,7 @@ or not." (buffer-read-only nil) (type (gnus-fetch-field "content-transfer-encoding"))) (when (or force - (and type (string-match "quoted-printable" type))) + (and type (string-match "quoted-printable" (downcase type)))) (gnus-headers-decode-quoted-printable) (goto-char (point-min)) (search-forward "\n\n" nil 'move) diff --git a/lisp/message.el b/lisp/message.el index d30b3f6d0..7159c0a10 100644 --- a/lisp/message.el +++ b/lisp/message.el @@ -1381,32 +1381,40 @@ the user from the mailer." (defun message-do-fcc () "Process Fcc headers in the current buffer." (let ((case-fold-search t) + (buf (current-buffer)) list file) (save-excursion + (set-buffer (get-buffer-create " *message temp*")) + (buffer-disable-undo (current-buffer)) + (erase-buffer) + (insert-buffer-substring buf) (save-restriction (message-narrow-to-headers) (while (setq file (mail-fetch-field "fcc")) (push file list) - (message-remove-header "fcc" nil t)) - ;; Process FCC operations. - (widen) - (while list - (setq file (pop list)) - (if (string-match "^[ \t]*|[ \t]*\\(.*\\)[ \t]*$" file) - ;; Pipe the article to the program in question. - (call-process-region (point-min) (point-max) shell-file-name - nil nil nil "-c" (match-string 1 file)) - ;; Save the article. - (setq file (expand-file-name file)) - (unless (file-exists-p (file-name-directory file)) - (make-directory (file-name-directory file) t)) - (if (and message-fcc-handler-function - (not (eq message-fcc-handler-function 'rmail-output))) - (funcall message-fcc-handler-function file) - (if (and (file-readable-p file) (mail-file-babyl-p file)) - (rmail-output file 1) - (let ((mail-use-rfc822 t)) - (rmail-output file 1 t t)))))))))) + (message-remove-header "fcc" nil t))) + (goto-char (point-min)) + (re-search-forward (concat "^" mail-header-separator "$")) + (replace-match "" t t) + ;; Process FCC operations. + (while list + (setq file (pop list)) + (if (string-match "^[ \t]*|[ \t]*\\(.*\\)[ \t]*$" file) + ;; Pipe the article to the program in question. + (call-process-region (point-min) (point-max) shell-file-name + nil nil nil "-c" (match-string 1 file)) + ;; Save the article. + (setq file (expand-file-name file)) + (unless (file-exists-p (file-name-directory file)) + (make-directory (file-name-directory file) t)) + (if (and message-fcc-handler-function + (not (eq message-fcc-handler-function 'rmail-output))) + (funcall message-fcc-handler-function file) + (if (and (file-readable-p file) (mail-file-babyl-p file)) + (rmail-output file 1) + (let ((mail-use-rfc822 t)) + (rmail-output file 1 t t)))))) + (kill-buffer (current-buffer))))) (defun message-cleanup-headers () "Do various automatic cleanups of the headers." @@ -1642,7 +1650,7 @@ give as trustworthy answer as possible." (defun message-user-mail-address () "Return the pertinent part of `user-mail-address'." (when (string-match - "\\(\\`\\|[ \t]\\)\\([^ \t@]+@[^ \t]+\\)\\(\\'\\|[ \t]\\)" + "\\(\\`\\|[ <\t]\\)\\([^ \t@]+@[^ \t]+\\)\\(\\'\\|[> \t]\\)" user-mail-address) (match-string 2 user-mail-address))) diff --git a/lisp/nnvirtual.el b/lisp/nnvirtual.el index 85a04307f..ca6805786 100644 --- a/lisp/nnvirtual.el +++ b/lisp/nnvirtual.el @@ -226,6 +226,9 @@ virtual group.") (when (nnvirtual-possibly-change-group group server) ;; Copy (un)read articles. (nnvirtual-update-reads) + (setq nnvirtual-mapping nil + nnvirtual-current-group nil + nnvirtual-component-groups nil) ;; We copy the marks from this group to the component ;; groups here. (nnvirtual-update-marked)) diff --git a/texi/ChangeLog b/texi/ChangeLog index d9ff48d82..827286205 100644 --- a/texi/ChangeLog +++ b/texi/ChangeLog @@ -1,3 +1,12 @@ +Tue Apr 9 23:41:15 1996 Lars Magne Ingebrigtsen + + * gnus.texi (GroupLens): Moved. + +Tue Apr 9 06:50:30 1996 Lars Magne Ingebrigtsen + + * gnus.texi (Contributors): Rewrite. + (Displaying Predictions): Further formatting. + Tue Apr 9 00:17:33 1996 Brad Miller * gnus.texi (GroupLens): New section. diff --git a/texi/gnus.texi b/texi/gnus.texi index 460d11ebd..fe5bd55ed 100644 --- a/texi/gnus.texi +++ b/texi/gnus.texi @@ -9406,6 +9406,7 @@ silently to help keep the sizes of the score files down. * Reverse Scoring:: That problem child of old is not problem. * Global Score Files:: Earth-spanning, ear-splitting score files. * Kill Files:: They are still here, but they can be ignored. +* GroupLens:: Getting predictions on what you like to read. @end menu @@ -10415,6 +10416,190 @@ A hook called in kill-file mode buffers. @end table +@node GroupLens +@section GroupLens +@cindex GroupLens + +GroupLens is a collaborative filtering system that helps you work +together with other people to find the quality news articles out of the +huge volume of news articles generated every day. + +To accomplish this the GroupLens system combines your opinions about +articles you have already read with the opinions of others who have done +likewise and gives you a personalized prediction for each unread news +article. Think of GroupLens as a matchmaker. GroupLens watches how you +rate articles, and finds other people that rate articles the same way. +Once it has found for you some people you agree with it tells you, in +the form of a prediction, what they thought of the article. You can use +this prediction to help you decide whether or not you want to read the +article. + +@menu +* Using GroupLens:: How to make Gnus use GroupLens. +* Rating Articles:: Letting GroupLens know how you rate articles. +* Displaying Predictions:: Displaying predictions given by GroupLens. +* GroupLens Variables:: Customizing GroupLens. +@end menu + + +@node Using GroupLens +@subsection Using GroupLens + +To use GroupLens you must register a pseudonym with your local Better +Bit Bureau (BBB). At the moment the only better bit in town is at +@samp{http://www.cs.umn.edu/Research/GroupLens/bbb.html}. + +Once you have registered you'll need to set a couple of variables. + +@table @code + +@item gnus-use-grouplens +@vindex gnus-use-grouplens +Setting this variable to a non-@code{nil} value will make Gnus hook into +all the relevant GroupLens functions. + +@item grouplens-pseudonym +@vindex grouplens-pseudonym +This variable should be set to the pseudonum you got when registering +with the Better Bit Bureau. + +@item grouplens-newsgroups +@vindex grouplens-newsgroups +A list of groups that you want to get GroupLens predictions for. + +@end table + +Thats the minimum of what you need to get up and running with GroupLens. +Once you've registered, GroupLens will start giving you scores for +articles based on the average of what other people think. But, to get +the real benefit of GroupLens you need to start rating articles +yourself. Then the scores GroupLens gives you will be personalized for +you, based on how the people you usually agree with have already rated. + + +@node Rating Articles +@subsection Rating Articles + +In GroupLens, an article is rated on a scale from 1 to 5, inclusive. +Where 1 means something like this article is a waste of bandwidth and 5 +means that the article was really good. The basic question to ask +yourself is, "on a scale from 1 to 5 would I like to see more articles +like this one?" + +There are four ways to enter a rating for an article in GroupLens. + +@table @kbd + +@item r +@kindex r (GroupLens) +@findex bbb-summary-rate-article +This function will prompt you for a rating on a scale of one to five. + +@item k +@kindex k (GroupLens) +@findex grouplens-score-thread +This function will prompt you for a rating, and rate all the articles in +the thread. This is really useful for some of those long running giant +threads in rec.humor. + +@end table + +The next two commands, @kbd{n} and @kbd{,} take a numerical prefix to be +the score of the article you're reading. + +@table @kbd + +@item 1-5 n +@kindex n (GroupLens) +@findex grouplens-next-unread-article +Rate the article and go to the next unread article. + +@item 1-5 , +@kindex , (GroupLens) +@findex grouplens-best-unread-article +Rate the article and go to the next unread article with the highest score. + +@end table + +If you want to give the current article a score of 4 and then go to the +next article, just type @kbd{4 n}. + + +@node Displaying Predictions +@subsection Displaying Predictions + +@vindex gnus-grouplens-override-scoring +There are two ways to display predictions in grouplens. One is to have +the grouplens scores contribute to, or override the regular gnus scoring +mechanism. This behavior is the default; however, some people prefer to +see the Gnus scores plus the grouplens scores. To get the separate +scoring behavior you need to set @code{gnus-grouplens-override-scoring} +to @code{nil}. + +@vindex grouplens-prediction-display +In either case, GroupLens gives you a few choices for how you would like +to see your predictions displayed. The display of predictions is +controlled by the @code{grouplens-prediction-display} variable. + +The following are legal values for that variable. + +@table @code +@item prediction-spot +The higher the prediction, the further to the right an @samp{*} is +displayed. + +@item confidence-interval +A numeric confidence interval. + +@item prediction-bar +The higher the prediction, the longer the bar. + +@item confidence-bar +Numerical confidence. + +@item confidence-spot +The spot gets bigger with more confidence. + +@item prediction-num +Plain-old numeric value. + +@item confidence-plus-minus +Prediction +/i confidence. + +@end table + + +@node GroupLens Variables +@subsection GroupLens Variables + +@table @code + +@item gnus-summary-grouplens-line-format +The summary line format used in summary buffers that are GroupLens +enhanced. It accepts the same specs as the normal summary line format +(@pxref{ Summary Buffer Lines}). The default is +@samp{%U%R%z%l%I%(%[%4L: %-20,20n%]%) %s\n}. + +@item grouplens-bbb-host +Host running the bbbd server. The default is +@samp{grouplens.cs.umn.edu}. + +@item grouplens-bbb-port +Port of the host running the bbbd server. The default is 9000. + +@item grouplens-score-offset +Offset the prediction by this value. In other words, subtract the +prediction value by this number to arrive at the effective score. The +default is 0. + +@item grouplens-score-scale-factor +This variable allows the user to magnify the effect of GroupLens scores. +The scale factor is applied after the offset. The default is 1. + +@end table + + + @node Various @chapter Various @@ -10429,8 +10614,7 @@ A hook called in kill-file mode buffers. * Buttons:: Get tendonitis in ten easy steps! * Daemons:: Gnus can do things behind your back. * NoCeM:: How to avoid spam and other fatty foods. -* Picons Pictures:: How to display pictures of what your reading. -* GroupLens:: Getting predictions on what you like to read. +* Picons:: How to display pictures of what your reading. * Various Various:: Things that are really various. @end menu @@ -11194,24 +11378,24 @@ might then see old spam. @end table -@node Picons Pictures -@section Picons Pictures +@node Picons +@section Picons So... You want to slow down your news reader even more! This is a good way to do so. Its also a great way to impress people staring over your shoulder as you read news. @menu -* Picons:: What are Picons and How do I get them. -* Picons Requirements:: Don't go further if you aren't using XEmacs. -* Picons Easy:: Displaying Picons -- the easy way. -* Picons Hard:: The way you should do it. You'll learn something. -* Picons Configuration:: Other variables you can trash/tweak/munge/play with. +* Picon Basics:: What are picons and How do I get them. +* Picon Requirements:: Don't go further if you aren't using XEmacs. +* Easy Picons:: Displaying Picons -- the easy way. +* Hard Picons:: The way you should do it. You'll learn something. +* Picon Configuration:: Other variables you can trash/tweak/munge/play with. @end menu -@node Picons -@subsection Picons +@node Picon Basics +@subsection Picon Basics What are Picons? To quote directly from the Picons Web site (@samp{http://www.cs.indiana.edu/picons/ftp/index.html}): @@ -11220,9 +11404,10 @@ What are Picons? To quote directly from the Picons Web site @dfn{Picons} is short for ``personal icons''. They're small, constrained images used to represent users and domains on the net, organized into databases so that the appropriate image for a given -e-mail address can be found. Besides users and domains, there are -picons databases for Usenet newsgroups and weather forecasts. The picons -are in either monochrome XBM format or color XPM and GIF formats. +e-mail address can be found. Besides users and domains, there are picon +databases for Usenet newsgroups and weather forecasts. The picons are +in either monochrome @code{XBM} format or color @code{XPM} and +@code{GIF} formats. @end quotation Please see the above mentioned web site for instructions on obtaining @@ -11234,25 +11419,26 @@ Gnus expects picons to be installed into a location pointed to by @code{gnus-picons-database}. -@node Picons Requirements -@subsection Picons Requirements +@node Picon Requirements +@subsection Picon Requirements -To use have gnus display Picons for you, you must be running XEmacs +To use have Gnus display Picons for you, you must be running XEmacs 19.13 or greater since all other versions of Emacs aren't yet able to display images. -Additionally, you must have xpm support compiled into XEmacs. +Additionally, you must have @code{xpm} support compiled into XEmacs. -If you want to display faces from X-Face: headers, you must have the -netpbm utilities installed, or munge the +@vindex gnus-picons-convert-x-face +If you want to display faces from @code{X-Face} headers, you must have +the @code{netpbm} utilities installed, or munge the @code{gnus-picons-convert-x-face} variable to use something else. -@node Picons Easy -@subsection Picons Easy +@node Easy Picons +@subsection Easy Picons -To enable the displaying of picons, simply put the followings line in -your @file{~/.gnus} file and start gnus. +To enable displaying picons, simply put the following line in your +@file{~/.gnus} file and start Gnus. @lisp (setq gnus-use-picons t) @@ -11262,33 +11448,37 @@ your @file{~/.gnus} file and start gnus. @end lisp -@node Picons Hard -@subsection Picons Hard +@node Hard Picons +@subsection Hard Picons -Gnus can display "Picons" for you as you enter and leave groups -and articles. It knows how to interact with three sections of the -picons database. Namely, it can display the picons newsgroup -pictures, author's face picture(s), and the authors domain. To enable -this feature, you need to first decide where to display them. +Gnus can display picons for you as you enter and leave groups and +articles. It knows how to interact with three sections of the picons +database. Namely, it can display the picons newsgroup pictures, +author's face picture(s), and the authors domain. To enable this +feature, you need to first decide where to display them. @table @code + @item gnus-picons-display-where @vindex gnus-picons-display-where -Where the Picons images should be displayed. It is @code{'picons} by -default (which by default maps to the buffer "*Picons*"). Other valid -places could be @code{'article}, @code{'summary}, or @code{"*scratch*"} -for all I care. Just make sure that you've made the buffer visible -using the @xref{Windows Configuration} routines. +Where the picon images should be displayed. It is @code{picons} by +default (which by default maps to the buffer @samp{*Picons*}). Other +valid places could be @code{article}, @code{summary}, or +@samp{"*scratch*"} for all I care. Just make sure that you've made the +buffer visible using the standard Gnus window configuration routines -- +@xref{Windows Configuration}. @end table Note: If you set @code{gnus-use-picons} to @code{t}, it will set up your -windows configuration for you to include the @code{picons} buffer. +window configuration for you to include the @code{picons} buffer. Now that you've made that decision, you need to add the following functions to the appropriate hooks so these pictures will get displayed at the right time. +@vindex gnus-article-display-hook +@vindex gnus-picons-display-where @table @code @item gnus-article-display-picons @findex gnus-article-display-picons @@ -11301,7 +11491,7 @@ the @code{gnus-article-display-hook}. Displays picons representing the current group. This function should be added to the @code{gnus-summary-prepare-hook} or to the @code{gnus-article-display-hook} if @code{gnus-picons-display-where} -is set to @code{'article}. +is set to @code{article}. @item gnus-picons-article-display-x-face @findex gnus-article-display-picons @@ -11317,8 +11507,9 @@ to the append flag of @code{add-hook}: (add-hook 'gnus-article-display-hook 'gnus-article-display-picons t) @end lisp -@node Picons Configuration -@subsection Picons Configuration + +@node Picon Configuration +@subsection Picon Configuration The following variables offer further control over how things are done, where things are located, and other useless stuff you really @@ -11328,8 +11519,8 @@ don't need to worry about. @item gnus-picons-database @vindex gnus-picons-database The location of the picons database. Should point to a directory -containing the "news", "domains", "users", etc... subdirectories. -Defaults to "/usr/local/faces". +containing the @file{news}, @file{domains}, @file{users} (and so on) +subdirectories. Defaults to @file{/usr/local/faces}. @item gnus-picons-news-directory @vindex gnus-picons-news-directory @@ -11338,125 +11529,35 @@ newsgroups. @item gnus-picons-user-directories @vindex gnus-picons-user-directories -List of subdirectories to search in @code{gnus-picons-database} for -user faces. Defaults to @code{'("local" "users" "usenix" -"misc/MISC")}. +List of subdirectories to search in @code{gnus-picons-database} for user +faces. Defaults to @code{("local" "users" "usenix" "misc/MISC")}. @item gnus-picons-domain-directories @vindex gnus-picons-domain-directories List of subdirectories to search in @code{gnus-picons-database} for -domain name faces. Defaults to @code{'("domains")}. Some people may -want to add @code{"unknown"} to this list. +domain name faces. Defaults to @code{("domains")}. Some people may +want to add @samp{unknown} to this list. @item gnus-picons-convert-x-face @vindex gnus-picons-convert-x-face -The command to use to convert the x-face header to a X bitmap (xbm). -Defaults to @code{(format "@{ echo '/* Width=48, Height=48 */'; uncompface; @} | icontopbm | pbmtoxbm > %s" gnus-picons-x-face-file-name)} +The command to use to convert the @code{X-Face} header to an X bitmap +(@code{xbm}). Defaults to @code{(format "@{ echo '/* Width=48, +Height=48 */'; uncompface; @} | icontopbm | pbmtoxbm > %s" +gnus-picons-x-face-file-name)} @item gnus-picons-x-face-file-name @vindex gnus-picons-x-face-file-name -Names a temporary file to store the x-face bitmap in. Defaults to -@code{(format "/tmp/picon-xface.%s.xbm" (user-login-name))}. +Names a temporary file to store the @code{X-Face} bitmap in. Defaults +to @code{(format "/tmp/picon-xface.%s.xbm" (user-login-name))}. @item gnus-picons-buffer @vindex gnus-picons-buffer -The name of the buffer that @code{'picons} points to. Defaults to -"*Icon Buffer*". +The name of the buffer that @code{picons} points to. Defaults to +@samp{*Icon Buffer*}. @end table -@node GroupLens -@section GroupLens -@cindex GroupLens -GroupLens is a collaborative filtering system that helps you work -together with other people to find the quality news articles out of the -huge volume of news articles generated every day. - -To accomplish this the GroupLens system combines your opinions about -articles you have already read with the opinions of others who have -done likewise and gives you a personalized prediction for each unread -news article. Think of GroupLens as a matchmaker. GroupLens watches -how you rate articles, and finds other people that rate articles the -same way. Once it has found for you some people you agree with it tells -you, in the form of a prediction, what they thought of the article. -You can use this prediction to help you decide whether or not you want -to read the article. - -@section Configuring gnus to use GroupLens - -To use GroupLens you must register a pseudonym with your local Better -Bit Bureau (BBB). At the moment the only better bit in town is at -@code{http://www.cs.umn.edu/Research/GroupLens/bbb.html}. -Once you have registered you'll need to set a couple of variables -@lisp -(setq gnus-use-grouplens t) -(setq grouplens-pseudonym my-pseudonym) -(setq grouplens-newsgroups "comp.lang.c++" "rec.humor") -@end lisp - -Thats the minimum of what you need to get up and running with -GroupLens. Once you've registered, GroupLens will start giving you -scores for articles based on the average of what other people think. -But, to get the real benefit of grouplens you need to start rating -articles yourself. Then the scores GroupLens gives you will be -personalized for you, based on how the people you usually agree with -have already rated. - -@section Rating Articles in GroupLens -In GroupLens, an article is rated on a scale from 1..5. Where 1 means -something like this article is a waste of bandwidth. and 5 means that -the article was really good. The basic question to ask yourself is, "on -a scale from 1 to 5 would I like to see more articles like this one?" -There are four ways to enter a rating for an article in GroupLens. -@table @kbd - -@item r -@findex bbb-summary-rate-article -This function will prompt you for a rating on a scale of one-to five - -@item N n -@findex grouplens-next-unread-article -Rate the article and go to the next unread article. - -@item N n -@findex grouplens-best-unread-article -Rate the article and go to the next unread article with the highest score - -@item k -@findex grouplens-score-thread -This function will prompt you for a rating, and rate all the articles in -the thread. This is really useful for some of those long running giant -threads in rec.humor. - -@end table - -@section Displaying predictions in grouplens -There are two ways to display predictions in grouplens. One is to have -the grouplens scores contribute to, or override the regular gnus scoring -mechanism. This behavior is the default; however, some people prefer to -see the gnus scores plus the grouplens scores. To get the separate -scoring behavior you need to set -@code{(setq gnus-grouplens-override-scoring nil)} - -In either case, GroupLens gives you a few choices for how you would like -to see your predictions displayed. The display of predictions is -controlled by the variable @code{grouplens-prediction-display} - - prediction-spot -- an * corresponding to the prediction between 1 and 5, - confidence-interval -- a numeric confidence interval - prediction-bar -- |##### | the longer the bar, the better the article, - confidence-bar -- | ----- | the prediction is in the middle of the bar, - confidence-spot -- | * | the spot gets bigger with more confidence, - prediction-num -- plain-old numeric value, - confidence-plus-minus -- prediction +/i confidence") - ----------------------------------------------------------------- -In particular, I'm pretty sure these last few lines will not look very -pretty without some additional texinfo magic, magic that is beyond me at -this time of the day. - - @node Various Various @section Various Various @cindex mode lines @@ -11823,47 +11924,66 @@ I would like to take this opportunity to thank the Academy for... oops, wrong show. @itemize @bullet -@item -Of course, @sc{gnus} was written by Masanobu @sc{Umeda}. -@item -Many excellent functions, especially dealing with scoring and -highlighting (as well as the @sc{soup} support) was written -by Per Abrahamsen. -@item -Design and graphics were done by Luis Fernandes. -@item -Innumerable bug fixes were written by Sudish Joseph. -@item -@code{gnus-topic} was written by Ilja Weis. -@item -Lots and lots of bugs were found and fixed by Steven L. Baur. -@item -The refcard was written by Vladimir Alexiev. -@item + +@item Masanobu @sc{Umeda} +The writer of the original @sc{gnus}. + +@item Per Abrahamsen +Scoring, highlighting and @sc{soup} code (as well as numerous other +things). + +@item Luis Fernandes +Design and graphics. + +@item Wes Hardaker +@file{gnus-picon.el} and the manual section on @dfn{picons} +(@pxref{Picons}). + +@item Brad Miller +@file{gnus-gl.el} and the GroupLens manual section (@pxref{GroupLens}). + +@item Sudish Joseph +Innumerable bug fixes. + +@item Ilja Weis +@file{gnus-topic.el}. + +@item Steven L. Baur +Lots and lots of bugs detections and fixes. + +@item Vladimir Alexiev +The refcard and reference booklets. + +@item Felix Lee & JWZ I stole some pieces from the XGnus distribution by Felix Lee and JWZ. -@item -@code{nnfolder} has been much enhanced by Scott Byer. -@item -The orphan scoring was written by Peter Mutsaers. -@item -GNU XEmacs support has been added by Fabrice Popineau. -@item -POP mail support was written by Ken Raeburn. -@item -Various bits and pieces, especially dealing with .newsrc files, were -suggested and added by Hallvard B Furuseth. -@item -Brian Edmonds has written @code{gnus-bbdb}. -@item -Ricardo Nassif and Mark Borges did the proff-reading (sic). -@item -Kevin Davidson came up with the name @dfn{ding}, so blame him. -@item -Peter Arius, Stainless Steel Rat, Ulrik Dickow, Jack Vinson, Daniel -Quinlan, Frank D. Cringle, Geoffrey T. Dairiki, and Andrew Eskilsson have -all contributed code and suggestions. + +@item Scott Byer +@file{nnfolder.el} enhancements & rewrite. + +@item Peter Mutsaers +Orphan article scoring code. + +@item Ken Raeburn +POP mail support. + +@item Hallvard B Furuseth +Various bits and pieces, especially dealing with .newsrc files. + +@item Brian Edmonds +@file{gnus-bbdb.el}. + +@item Ricardo Nassif and Mark Borges +Proof-reading. + +@item Kevin Davidson +Came up with the name @dfn{ding}, so blame him. + @end itemize +Peter Arius, Stainless Steel Rat, Ulrik Dickow, Jack Vinson, Daniel +Quinlan, Frank D. Cringle, Geoffrey T. Dairiki, Fabrice Popineau and +Andrew Eskilsson have all contributed code and suggestions. + @node New Features @subsection New Features -- 2.25.1