comparison lisp/gnus/gnus-gl.el @ 98:0d2f883870bc r20-1b1

Import from CVS: tag r20-1b1
author cvs
date Mon, 13 Aug 2007 09:13:56 +0200
parents 131b0175ea99
children 360340f9fd5f
comparison
equal deleted inserted replaced
97:498bf5da1c90 98:0d2f883870bc
1 ;;; gnus-gl.el --- an interface to GroupLens for Gnus 1 ;;; gnus-gl.el --- an interface to GroupLens for Gnus
2 ;; Copyright (C) 1995,96 Free Software Foundation, Inc. 2 ;; Copyright (C) 1995,96,97 Free Software Foundation, Inc.
3 3
4 ;; Author: Brad Miller <bmiller@cs.umn.edu> 4 ;; Author: Brad Miller <bmiller@cs.umn.edu>
5 ;; Keywords: news, score 5 ;; Keywords: news, score
6 6
7 ;; This file is part of GNU Emacs. 7 ;; This file is part of GNU Emacs.
67 ;; 67 ;;
68 ;; USING GROUPLENS 68 ;; USING GROUPLENS
69 ;; How do I Rate an article?? 69 ;; How do I Rate an article??
70 ;; Before you type n to go to the next article, hit a number from 1-5 70 ;; Before you type n to go to the next article, hit a number from 1-5
71 ;; Type r in the summary buffer and you will be prompted. 71 ;; Type r in the summary buffer and you will be prompted.
72 ;; Note that when you're in grouplens-minor-mode 'r' maskes the 72 ;; Note that when you're in grouplens-minor-mode 'r' masks the
73 ;; usual reply binding for 'r' 73 ;; usual reply binding for 'r'
74 ;; 74 ;;
75 ;; What if, Gasp, I find a bug??? 75 ;; What if, Gasp, I find a bug???
76 ;; Please type M-x gnus-gl-submit-bug-report. This will set up a 76 ;; Please type M-x gnus-gl-submit-bug-report. This will set up a
77 ;; mail buffer with the state of variables and buffers that will help 77 ;; mail buffer with the state of variables and buffers that will help
78 ;; me debug the problem. A short description up front would help too! 78 ;; me debug the problem. A short description up front would help too!
79 ;; 79 ;;
80 ;; How do I display the prediction for an aritcle: 80 ;; How do I display the prediction for an article:
81 ;; If you set the gnus-summary-line-format as shown above, the score 81 ;; If you set the gnus-summary-line-format as shown above, the score
82 ;; (prediction) will be shown automatically. 82 ;; (prediction) will be shown automatically.
83 ;; 83 ;;
84 ;; 84 ;;
85 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 85 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
119 119
120 ;;; Code: 120 ;;; Code:
121 121
122 (require 'gnus-score) 122 (require 'gnus-score)
123 (require 'cl) 123 (require 'cl)
124 (require 'gnus)
124 125
125 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 126 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
126 ;;;; User variables 127 ;;;; User variables
127 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 128 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
128 129
129 (defvar gnus-summary-grouplens-line-format 130 (defvar gnus-summary-grouplens-line-format
130 "%U\%R\%z%l%I\%(%[%4L: %-20,20n%]%) %s\n" 131 "%U\%R\%z%l%I\%(%[%4L: %-20,20n%]%) %s\n"
131 "*The line format spec in summary GroupLens mode buffers.") 132 "*The line format spec in summary GroupLens mode buffers.")
132 133
133 (defvar grouplens-pseudonym "" 134 (defvar grouplens-pseudonym ""
134 "User's pseudonym. This pseudonym is obtained during the registration process") 135 "User's pseudonym.
136 This pseudonym is obtained during the registration process")
135 137
136 (defvar grouplens-bbb-host "grouplens.cs.umn.edu" 138 (defvar grouplens-bbb-host "grouplens.cs.umn.edu"
137 "Host where the bbbd is running" ) 139 "Host where the bbbd is running" )
138 140
139 (defvar grouplens-bbb-port 9000 141 (defvar grouplens-bbb-port 9000
140 "Port where the bbbd is listening" ) 142 "Port where the bbbd is listening" )
141 143
142 (defvar grouplens-newsgroups 144 (defvar grouplens-newsgroups
143 '("comp.lang.c++" "rec.humor" "rec.food.recipes" "comp.groupware" 145 '("comp.groupware" "comp.human-factors" "comp.lang.c++"
146 "comp.lang.java" "comp.os.linux.admin" "comp.os.linux.advocacy"
147 "comp.os.linux.announce" "comp.os.linux.answers"
148 "comp.os.linux.development" "comp.os.linux.development.apps"
149 "comp.os.linux.development.system" "comp.os.linux.hardware"
150 "comp.os.linux.help" "comp.os.linux.m68k" "comp.os.linux.misc"
151 "comp.os.linux.networking" "comp.os.linux.setup" "comp.os.linux.x"
144 "mn.general" "rec.arts.movies" "rec.arts.movies.current-films" 152 "mn.general" "rec.arts.movies" "rec.arts.movies.current-films"
145 "comp.lang.java" "comp.os.linux.announce" "comp.os.linux.misc" 153 "rec.food.recipes" "rec.humor")
146 "comp.os.linux.development.apps" "comp.os.linux.development.system")
147 "*Groups that are part of the GroupLens experiment.") 154 "*Groups that are part of the GroupLens experiment.")
148 155
149 (defvar grouplens-prediction-display 'prediction-spot 156 (defvar grouplens-prediction-display 'prediction-spot
150 "valid values are: 157 "valid values are:
151 prediction-spot -- an * corresponding to the prediction between 1 and 5, 158 prediction-spot -- an * corresponding to the prediction between 1 and 5,
173 (defvar grouplens-score-scale-factor 1 180 (defvar grouplens-score-scale-factor 1
174 "This variable allows the user to magnify the effect of GroupLens scores. 181 "This variable allows the user to magnify the effect of GroupLens scores.
175 The scale factor is applied after the offset.") 182 The scale factor is applied after the offset.")
176 183
177 (defvar gnus-grouplens-override-scoring 'override 184 (defvar gnus-grouplens-override-scoring 'override
178 "Tell Grouplens to override the normal Gnus scoring mechanism. 185 "Tell GroupLens to override the normal Gnus scoring mechanism.
179 GroupLens scores can be combined with gnus scores in one of three ways. 186 GroupLens scores can be combined with gnus scores in one of three ways.
180 'override -- just use grouplens predictions for grouplens groups 187 'override -- just use grouplens predictions for grouplens groups
181 'combine -- combine grouplens scores with gnus scores 188 'combine -- combine grouplens scores with gnus scores
182 'separate -- treat grouplens scores completely separate from gnus") 189 'separate -- treat grouplens scores completely separate from gnus")
183 190
184 191
185 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 192 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
186 ;;;; Program global variables 193 ;;;; Program global variables
187 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 194 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
188 (defvar grouplens-bbb-token "0" 195 (defvar grouplens-bbb-token nil
189 "Current session token number") 196 "Current session token number")
190 197
191 (defvar grouplens-bbb-process nil 198 (defvar grouplens-bbb-process nil
192 "Process Id of current bbbd network stream process") 199 "Process Id of current bbbd network stream process")
193 200
195 "Buffer associated with the BBBD process") 202 "Buffer associated with the BBBD process")
196 203
197 (defvar grouplens-rating-alist nil 204 (defvar grouplens-rating-alist nil
198 "Current set of message-id rating pairs") 205 "Current set of message-id rating pairs")
199 206
200 (defvar grouplens-current-hashtable (make-hash-table :test 'equal :size 100)) 207 (defvar grouplens-current-hashtable nil
201 ;; this seems like a pretty ugly way to get around the problem, but If 208 "A hashtable to hold predictions from the BBB")
202 ;; I don't do this, then the compiler complains when I call gethash
203 ;;
204 (eval-when-compile (setq grouplens-current-hashtable
205 (make-hash-table :test 'equal :size 100)))
206 209
207 (defvar grouplens-current-group nil) 210 (defvar grouplens-current-group nil)
208 211
209 (defvar bbb-mid-list nil) 212 ;;(defvar bbb-alist nil)
210
211 (defvar bbb-alist nil)
212 213
213 (defvar bbb-timeout-secs 10 214 (defvar bbb-timeout-secs 10
214 "Number of seconds to wait for some response from the BBB. 215 "Number of seconds to wait for some response from the BBB.
215 If this times out we give up and assume that something has died..." ) 216 If this times out we give up and assume that something has died..." )
216 217
218 "Message-ID of the last article read.") 219 "Message-ID of the last article read.")
219 220
220 (defvar bbb-read-point) 221 (defvar bbb-read-point)
221 (defvar bbb-response-point) 222 (defvar bbb-response-point)
222 223
224 (defun bbb-renew-hash-table ()
225 (setq grouplens-current-hashtable (make-vector 100 0)))
226
227 (bbb-renew-hash-table)
228
223 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 229 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
224 ;;;; Utility Functions 230 ;;;; Utility Functions
225 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 231 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
232
226 (defun bbb-connect-to-bbbd (host port) 233 (defun bbb-connect-to-bbbd (host port)
227 (unless grouplens-bbb-buffer 234 (unless grouplens-bbb-buffer
228 (setq grouplens-bbb-buffer 235 (setq grouplens-bbb-buffer
229 (get-buffer-create (format " *BBBD trace: %s*" host))) 236 (get-buffer-create (format " *BBBD trace: %s*" host)))
230 (save-excursion 237 (save-excursion
231 (set-buffer grouplens-bbb-buffer) 238 (set-buffer grouplens-bbb-buffer)
232 (make-local-variable 'bbb-read-point) 239 (make-local-variable 'bbb-read-point)
240 (make-local-variable 'bbb-response-point)
233 (setq bbb-read-point (point-min)))) 241 (setq bbb-read-point (point-min))))
242
243 ;; if an old process is still running for some reason, kill it
244 (when grouplens-bbb-process
245 (ignore-errors
246 (when (eq 'open (process-status grouplens-bbb-process))
247 (set-process-buffer grouplens-bbb-process nil)
248 (delete-process grouplens-bbb-process))))
249
234 ;; clear the trace buffer of old output 250 ;; clear the trace buffer of old output
235 (save-excursion 251 (save-excursion
236 (set-buffer grouplens-bbb-buffer) 252 (set-buffer grouplens-bbb-buffer)
237 (erase-buffer)) 253 (erase-buffer))
254
238 ;; open the connection to the server 255 ;; open the connection to the server
239 (setq grouplens-bbb-process nil)
240 (catch 'done 256 (catch 'done
241 (condition-case error 257 (condition-case error
242 (setq grouplens-bbb-process 258 (setq grouplens-bbb-process
243 (open-network-stream "BBBD" grouplens-bbb-buffer host port)) 259 (open-network-stream "BBBD" grouplens-bbb-buffer host port))
244 (error (gnus-message 3 "Error: Failed to connect to BBB") 260 (error (gnus-message 3 "Error: Failed to connect to BBB")
245 nil)) 261 nil))
246 (and (null grouplens-bbb-process) 262 (and (null grouplens-bbb-process)
247 (throw 'done nil)) 263 (throw 'done nil))
248 ;; (set-process-filter grouplens-bbb-process 'bbb-process-filter)
249 (save-excursion 264 (save-excursion
250 (set-buffer grouplens-bbb-buffer) 265 (set-buffer grouplens-bbb-buffer)
251 (setq bbb-read-point (point-min)) 266 (setq bbb-read-point (point-min))
252 (or (bbb-read-response grouplens-bbb-process) 267 (or (bbb-read-response grouplens-bbb-process)
253 (throw 'done nil)))) 268 (throw 'done nil))))
269
270 ;; return the process
254 grouplens-bbb-process) 271 grouplens-bbb-process)
255
256 ;; (defun bbb-process-filter (process output)
257 ;; (save-excursion
258 ;; (set-buffer (bbb-process-buffer process))
259 ;; (goto-char (point-max))
260 ;; (insert output)))
261 272
262 (defun bbb-send-command (process command) 273 (defun bbb-send-command (process command)
263 (goto-char (point-max)) 274 (goto-char (point-max))
264 (insert command) 275 (insert command)
265 (insert "\r\n") 276 (insert "\r\n")
266 (setq bbb-read-point (point)) 277 (setq bbb-read-point (point))
267 (setq bbb-response-point (point)) 278 (setq bbb-response-point (point))
268 (set-marker (process-mark process) (point)) ; process output also comes here 279 (set-marker (process-mark process) (point)) ; process output also comes here
269 (process-send-string process command) 280 (process-send-string process command)
270 (process-send-string process "\r\n")) 281 (process-send-string process "\r\n")
271 282 (process-send-eof process))
272 (defun bbb-read-response (process) ; &optional return-response-string) 283
284 (defun bbb-read-response (process)
273 "This function eats the initial response of OK or ERROR from the BBB." 285 "This function eats the initial response of OK or ERROR from the BBB."
274 (let ((case-fold-search nil) 286 (let ((case-fold-search nil)
275 match-end) 287 match-end)
276 (goto-char bbb-read-point) 288 (goto-char bbb-read-point)
277 (while (and (not (search-forward "\r\n" nil t)) 289 (while (and (not (search-forward "\r\n" nil t))
278 (accept-process-output process bbb-timeout-secs)) 290 (accept-process-output process bbb-timeout-secs))
279 (goto-char bbb-read-point)) 291 (goto-char bbb-read-point))
280 (setq match-end (point)) 292 (setq match-end (point))
288 (defun bbb-login () 300 (defun bbb-login ()
289 "return the token number if login is successful, otherwise return nil" 301 "return the token number if login is successful, otherwise return nil"
290 (interactive) 302 (interactive)
291 (setq grouplens-bbb-token nil) 303 (setq grouplens-bbb-token nil)
292 (if (not (equal grouplens-pseudonym "")) 304 (if (not (equal grouplens-pseudonym ""))
293 (let ((bbb-process 305 (let ((bbb-process
294 (bbb-connect-to-bbbd grouplens-bbb-host grouplens-bbb-port))) 306 (bbb-connect-to-bbbd grouplens-bbb-host grouplens-bbb-port)))
295 (if bbb-process 307 (if bbb-process
296 (save-excursion 308 (save-excursion
297 (set-buffer (process-buffer bbb-process)) 309 (set-buffer (process-buffer bbb-process))
298 (bbb-send-command bbb-process 310 (bbb-send-command bbb-process
299 (concat "login " grouplens-pseudonym)) 311 (concat "login " grouplens-pseudonym))
300 (if (bbb-read-response bbb-process) 312 (if (bbb-read-response bbb-process)
301 (setq grouplens-bbb-token (bbb-extract-token-number)) 313 (setq grouplens-bbb-token (bbb-extract-token-number))
302 (gnus-message 3 "Error: Grouplens login failed"))))) 314 (gnus-message 3 "Error: GroupLens login failed")))))
303 (gnus-message 3 "Error: you must set a pseudonym")) 315 (gnus-message 3 "Error: you must set a pseudonym"))
304 grouplens-bbb-token) 316 grouplens-bbb-token)
305 317
306 (defun bbb-extract-token-number () 318 (defun bbb-extract-token-number ()
307 (let ((token-pos (search-forward "token=" nil t) )) 319 (let ((token-pos (search-forward "token=" nil t)))
308 (if (looking-at "[0-9]+") 320 (when (looking-at "[0-9]+")
309 (buffer-substring token-pos (match-end 0))))) 321 (buffer-substring token-pos (match-end 0)))))
310 322
311 (gnus-add-shutdown 'bbb-logout 'gnus) 323 (gnus-add-shutdown 'bbb-logout 'gnus)
312 324
313 (defun bbb-logout () 325 (defun bbb-logout ()
314 "logout of bbb session" 326 "logout of bbb session"
315 (let ((bbb-process 327 (when grouplens-bbb-token
316 (bbb-connect-to-bbbd grouplens-bbb-host grouplens-bbb-port))) 328 (let ((bbb-process
317 (if bbb-process 329 (bbb-connect-to-bbbd grouplens-bbb-host grouplens-bbb-port)))
318 (save-excursion 330 (when bbb-process
331 (save-excursion
319 (set-buffer (process-buffer bbb-process)) 332 (set-buffer (process-buffer bbb-process))
320 (bbb-send-command bbb-process (concat "logout " grouplens-bbb-token)) 333 (bbb-send-command bbb-process (concat "logout " grouplens-bbb-token))
321 (bbb-read-response bbb-process)) 334 (bbb-read-response bbb-process))))))
322 nil)))
323 335
324 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 336 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
325 ;;;; Get Predictions 337 ;;;; Get Predictions
326 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 338 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
327 339
328 (defun bbb-build-mid-scores-alist (groupname) 340 (defun bbb-build-mid-scores-alist (groupname)
329 "this function can be called as part of the function to return the 341 "this function can be called as part of the function to return the
330 list of score files to use. See the gnus variable 342 list of score files to use. See the gnus variable
331 gnus-score-find-score-files-function. 343 gnus-score-find-score-files-function.
332 344
333 *Note:* If you want to use grouplens scores along with calculated scores, 345 *Note:* If you want to use grouplens scores along with calculated scores,
334 you should see the offset and scale variables. At this point, I don't 346 you should see the offset and scale variables. At this point, I don't
335 recommend using both scores and grouplens predictions together." 347 recommend using both scores and grouplens predictions together."
336 (setq grouplens-current-group groupname) 348 (setq grouplens-current-group groupname)
337 (if (member groupname grouplens-newsgroups) 349 (when (member groupname grouplens-newsgroups)
338 (let* ((mid-list (bbb-get-all-mids)) 350 (setq grouplens-previous-article nil)
339 (predict-list (bbb-get-predictions mid-list groupname))) 351 ;; scores-alist should be a list of lists:
340 (setq grouplens-previous-article nil) 352 ;; ((("message-id" ("<mid1>" score1 nil s) ("<mid2> score2 nil s))))
341 ;; scores-alist should be a list of lists: 353 ;;`((("message-id" . ,predict-list))) ; Yes, this is the return value
342 ;; ((("message-id" ("<mid1>" score1 nil s) ("<mid2> score2 nil s)))) 354 (list
343 ;;`((("message-id" . ,predict-list))) ; Yes, this is the return value 355 (list
344 (list (list (list (append (list "message-id") predict-list))))) 356 (list (append (list "message-id")
345 nil)) 357 (bbb-get-predictions (bbb-get-all-mids) groupname)))))))
346 358
347 (defun bbb-get-predictions (midlist groupname) 359 (defun bbb-get-predictions (midlist groupname)
348 "Ask the bbb for predictions, and build up the score alist." 360 "Ask the bbb for predictions, and build up the score alist."
349 (if (or (null grouplens-bbb-token) 361 (gnus-message 5 "Fetching Predictions...")
350 (equal grouplens-bbb-token "0")) 362 (if grouplens-bbb-token
351 (progn 363 (let ((bbb-process (bbb-connect-to-bbbd grouplens-bbb-host
352 (gnus-message 3 "Error: You are not logged in to a BBB") 364 grouplens-bbb-port)))
353 nil) 365 (when bbb-process
354 (gnus-message 5 "Fetching Predictions...") 366 (save-excursion
355 (let (predict-list
356 (predict-command (bbb-build-predict-command midlist groupname
357 grouplens-bbb-token))
358 (bbb-process (bbb-connect-to-bbbd grouplens-bbb-host
359 grouplens-bbb-port)))
360 (if bbb-process
361 (save-excursion
362 (set-buffer (process-buffer bbb-process)) 367 (set-buffer (process-buffer bbb-process))
363 (bbb-send-command bbb-process predict-command) 368 (bbb-send-command bbb-process
369 (bbb-build-predict-command midlist groupname
370 grouplens-bbb-token))
364 (if (bbb-read-response bbb-process) 371 (if (bbb-read-response bbb-process)
365 (setq predict-list (bbb-get-prediction-response bbb-process)) 372 (bbb-get-prediction-response bbb-process)
366 (gnus-message 1 "Invalid Token, login and try again") 373 (gnus-message 1 "Invalid Token, login and try again")
367 (ding)))) 374 (ding)))))
368 (setq bbb-alist predict-list)))) 375 (gnus-message 3 "Error: You are not logged in to a BBB")
376 (ding)))
369 377
370 (defun bbb-get-all-mids () 378 (defun bbb-get-all-mids ()
371 (let ((index (nth 1 (assoc "message-id" gnus-header-index))) 379 (mapcar (function (lambda (x) (mail-header-id x))) gnus-newsgroup-headers))
372 (articles gnus-newsgroup-headers)
373 art this)
374 (setq bbb-mid-list nil)
375 (while articles
376 (progn (setq art (car articles)
377 this (aref art index)
378 articles (cdr articles))
379 (setq bbb-mid-list (cons this bbb-mid-list))))
380 bbb-mid-list))
381 380
382 (defun bbb-build-predict-command (mlist grpname token) 381 (defun bbb-build-predict-command (mlist grpname token)
383 (let ((cmd (concat "getpredictions " token " " grpname "\r\n")) 382 (concat "getpredictions " token " " grpname "\r\n"
384 art) 383 (mapconcat 'identity mlist "\r\n") "\r\n.\r\n"))
385 (while mlist
386 (setq art (car mlist)
387 cmd (concat cmd art "\r\n")
388 mlist (cdr mlist)))
389 (setq cmd (concat cmd ".\r\n"))
390 cmd))
391 384
392 (defun bbb-get-prediction-response (process) 385 (defun bbb-get-prediction-response (process)
393 (let ((case-fold-search nil) 386 (let ((case-fold-search nil))
394 match-end)
395 (goto-char bbb-read-point) 387 (goto-char bbb-read-point)
396 (while (and (not (search-forward ".\r\n" nil t)) 388 (while (and (not (search-forward ".\r\n" nil t))
397 (accept-process-output process bbb-timeout-secs)) 389 (accept-process-output process bbb-timeout-secs))
398 (goto-char bbb-read-point)) 390 (goto-char bbb-read-point))
399 (setq match-end (point)) 391 (goto-char (+ bbb-response-point 4));; we ought to be right before OK
400 (goto-char (+ bbb-response-point 4)) ;; we ought to be right before OK
401 (bbb-build-response-alist))) 392 (bbb-build-response-alist)))
402 393
403 ;; build-response-alist assumes that the cursor has been positioned at 394 ;; build-response-alist assumes that the cursor has been positioned at
404 ;; the first line of the list of mid/rating pairs. For now we will 395 ;; the first line of the list of mid/rating pairs.
405 ;; use a prediction of 99 to signify no prediction. Ultimately, we
406 ;; should just ignore messages with no predictions.
407 (defun bbb-build-response-alist () 396 (defun bbb-build-response-alist ()
408 (let ((resp nil) 397 (let (resp mid pred)
409 (match-end (point)))
410 (setq grouplens-current-hashtable (make-hash-table :test 'equal :size 100))
411 (while 398 (while
412 (cond ((looking-at "\\(<.*>\\) :nopred=") 399 (cond
413 (push `(,(bbb-get-mid) ,gnus-summary-default-score nil s) resp) 400 ((looking-at "\\(<.*>\\) :nopred=")
414 (forward-line 1) 401 ;;(push `(,(bbb-get-mid) ,gnus-summary-default-score nil s) resp)
415 t) 402 (forward-line 1)
416 ((looking-at "\\(<.*>\\) :pred=\\([0-9]\.[0-9][0-9]\\) :conflow=\\([0-9]\.[0-9][0-9]\\) :confhigh=\\([0-9]\.[0-9][0-9]\\)") 403 t)
417 (push `(,(bbb-get-mid) ,(bbb-get-pred) nil s) resp) 404 ((looking-at "\\(<.*>\\) :pred=\\([0-9]\.[0-9][0-9]\\) :conflow=\\([0-9]\.[0-9][0-9]\\) :confhigh=\\([0-9]\.[0-9][0-9]\\)")
418 (cl-puthash (bbb-get-mid) 405 (setq mid (bbb-get-mid)
419 (list (bbb-get-pred) (bbb-get-confl) (bbb-get-confh)) 406 pred (bbb-get-pred))
420 grouplens-current-hashtable) 407 (push `(,mid ,pred nil s) resp)
421 (forward-line 1) 408 (gnus-sethash mid (list pred (bbb-get-confl) (bbb-get-confh))
422 t) 409 grouplens-current-hashtable)
423 ((looking-at "\\(<.*>\\) :pred=\\([0-9]\.[0-9][0-9]\\)") 410 (forward-line 1)
424 (push `(,(bbb-get-mid) ,(bbb-get-pred) nil s) resp) 411 t)
425 (cl-puthash (bbb-get-mid) 412 ((looking-at "\\(<.*>\\) :pred=\\([0-9]\.[0-9][0-9]\\)")
426 (list (bbb-get-pred) 0 0) 413 (setq mid (bbb-get-mid)
427 grouplens-current-hashtable) 414 pred (bbb-get-pred))
428 (forward-line 1) 415 (push `(,mid ,pred nil s) resp)
429 t) 416 (gnus-sethash mid (list pred 0 0) grouplens-current-hashtable)
430 (t nil))) 417 (forward-line 1)
418 t)
419 (t nil)))
431 resp)) 420 resp))
432 421
433 ;; these two functions assume that there is an active match lying 422 ;; these "get" functions assume that there is an active match lying
434 ;; around. Where the first parenthesized expression is the 423 ;; around. Where the first parenthesized expression is the
435 ;; message-id, and the second is the prediction. Since gnus assumes 424 ;; message-id, and the second is the prediction, the third and fourth
436 ;; that scores are integer values?? we round the prediction. 425 ;; are the confidence interval
426 ;;
427 ;; Since gnus assumes that scores are integer values?? we round the
428 ;; prediction.
437 (defun bbb-get-mid () 429 (defun bbb-get-mid ()
438 (buffer-substring (match-beginning 1) (match-end 1))) 430 (buffer-substring (match-beginning 1) (match-end 1)))
439 431
440 (defun bbb-get-pred () 432 (defun bbb-get-pred ()
441 (let ((tpred (string-to-number (buffer-substring 433 (let ((tpred (string-to-number (buffer-substring (match-beginning 2)
442 (match-beginning 2) 434 (match-end 2)))))
443 (match-end 2)))))
444 (if (> tpred 0) 435 (if (> tpred 0)
445 (round (* grouplens-score-scale-factor (+ grouplens-score-offset tpred))) 436 (round (* grouplens-score-scale-factor
437 (+ grouplens-score-offset tpred)))
446 1))) 438 1)))
447 439
448 (defun bbb-get-confl () 440 (defun bbb-get-confl ()
449 (string-to-number (buffer-substring (match-beginning 3) (match-end 3)))) 441 (string-to-number (buffer-substring (match-beginning 4) (match-end 4))))
450 442
451 (defun bbb-get-confh () 443 (defun bbb-get-confh ()
452 (string-to-number (buffer-substring (match-beginning 4) (match-end 4)))) 444 (string-to-number (buffer-substring (match-beginning 4) (match-end 4))))
453 445
454 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 446 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
461 453
462 (defvar gnus-tmp-score) 454 (defvar gnus-tmp-score)
463 (defun bbb-grouplens-score (header) 455 (defun bbb-grouplens-score (header)
464 (if (eq gnus-grouplens-override-scoring 'separate) 456 (if (eq gnus-grouplens-override-scoring 'separate)
465 (bbb-grouplens-other-score header) 457 (bbb-grouplens-other-score header)
466 (let* ((rate-string (make-string 12 ? )) 458 (let* ((rate-string (make-string 12 ?\ ))
467 (mid (aref header (nth 1 (assoc "message-id" gnus-header-index)))) 459 (mid (mail-header-id header))
468 (hashent (gethash mid grouplens-current-hashtable)) 460 (hashent (gnus-gethash mid grouplens-current-hashtable))
469 (iscore gnus-tmp-score) 461 (iscore gnus-tmp-score)
470 (low (car (cdr hashent))) 462 (low (car (cdr hashent)))
471 (high (car (cdr (cdr hashent))))) 463 (high (car (cdr (cdr hashent)))))
472 (aset rate-string 0 ?|) 464 (aset rate-string 0 ?|)
473 (aset rate-string 11 ?|) 465 (aset rate-string 11 ?|)
474 (unless (member grouplens-current-group grouplens-newsgroups) 466 (unless (member grouplens-current-group grouplens-newsgroups)
475 (unless (equal grouplens-prediction-display 'prediction-num) 467 (unless (equal grouplens-prediction-display 'prediction-num)
476 (cond ((< iscore 0) 468 (cond ((< iscore 0)
477 (setq iscore 1)) 469 (setq iscore 1))
478 ((> iscore 5) 470 ((> iscore 5)
479 (setq iscore 5)))) 471 (setq iscore 5))))
480 (setq low 0) 472 (setq low 0)
481 (setq high 0)) 473 (setq high 0))
482 (if (and (bbb-valid-score iscore) 474 (if (and (bbb-valid-score iscore)
483 (not (null mid))) 475 (not (null mid)))
484 (cond 476 (cond
485 ;; prediction-spot 477 ;; prediction-spot
486 ((equal grouplens-prediction-display 'prediction-spot) 478 ((equal grouplens-prediction-display 'prediction-spot)
487 (setq rate-string (bbb-fmt-prediction-spot rate-string iscore))) 479 (setq rate-string (bbb-fmt-prediction-spot rate-string iscore)))
506 ) 498 )
507 (t (gnus-message 3 "Invalid prediction display type"))) 499 (t (gnus-message 3 "Invalid prediction display type")))
508 (aset rate-string 5 ?N) (aset rate-string 6 ?A)) 500 (aset rate-string 5 ?N) (aset rate-string 6 ?A))
509 rate-string))) 501 rate-string)))
510 502
511 ;;
512 ;; Gnus user format function that doesn't depend on 503 ;; Gnus user format function that doesn't depend on
513 ;; bbb-build-mid-scores-alist being used as the score function, but is 504 ;; bbb-build-mid-scores-alist being used as the score function, but is
514 ;; instead called from gnus-select-group-hook. -- LAB 505 ;; instead called from gnus-select-group-hook. -- LAB
515 (defun bbb-grouplens-other-score (header) 506 (defun bbb-grouplens-other-score (header)
516 (if (not (member grouplens-current-group grouplens-newsgroups)) 507 (if (not (member grouplens-current-group grouplens-newsgroups))
517 ;; Return an empty string 508 ;; Return an empty string
518 "" 509 ""
519 (let* ((rate-string (make-string 12 ? )) 510 (let* ((rate-string (make-string 12 ?\ ))
520 (mid (aref header (nth 1 (assoc "message-id" gnus-header-index)))) 511 (mid (mail-header-id header))
521 (hashent (gethash mid grouplens-current-hashtable)) 512 (hashent (gnus-gethash mid grouplens-current-hashtable))
522 (pred (or (nth 0 hashent) 0)) 513 (pred (or (nth 0 hashent) 0))
523 (low (nth 1 hashent)) 514 (low (nth 1 hashent))
524 (high (nth 2 hashent))) 515 (high (nth 2 hashent)))
525 ;; Init rate-string 516 ;; Init rate-string
526 (aset rate-string 0 ?|) 517 (aset rate-string 0 ?|)
527 (aset rate-string 11 ?|) 518 (aset rate-string 11 ?|)
528 (unless (equal grouplens-prediction-display 'prediction-num) 519 (unless (equal grouplens-prediction-display 'prediction-num)
529 (cond ((< pred 0) 520 (cond ((< pred 0)
530 (setq pred 1)) 521 (setq pred 1))
531 ((> pred 5) 522 ((> pred 5)
532 (setq pred 5)))) 523 (setq pred 5))))
533 ;; If no entry in BBB hash mark rate string as NA and return 524 ;; If no entry in BBB hash mark rate string as NA and return
534 (cond 525 (cond
535 ((null hashent) 526 ((null hashent)
536 (aset rate-string 5 ?N) 527 (aset rate-string 5 ?N)
537 (aset rate-string 6 ?A) 528 (aset rate-string 6 ?A)
538 rate-string) 529 rate-string)
539 530
540 ((equal grouplens-prediction-display 'prediction-spot) 531 ((equal grouplens-prediction-display 'prediction-spot)
541 (bbb-fmt-prediction-spot rate-string pred)) 532 (bbb-fmt-prediction-spot rate-string pred))
558 ((equal grouplens-prediction-display 'confidence-plus-minus) 549 ((equal grouplens-prediction-display 'confidence-plus-minus)
559 (bbb-fmt-confidence-plus-minus pred low high)) 550 (bbb-fmt-confidence-plus-minus pred low high))
560 551
561 (t 552 (t
562 (gnus-message 3 "Invalid prediction display type") 553 (gnus-message 3 "Invalid prediction display type")
563 (aset rate-string 0 ?|) 554 (aset rate-string 0 ?|)
564 (aset rate-string 11 ?|) 555 (aset rate-string 11 ?|)
565 rate-string))))) 556 rate-string)))))
566 557
567 (defun bbb-valid-score (score) 558 (defun bbb-valid-score (score)
568 (or (equal grouplens-prediction-display 'prediction-num) 559 (or (equal grouplens-prediction-display 'prediction-num)
594 (if (bbb-have-confidence low high) 585 (if (bbb-have-confidence low high)
595 (format "|%3.1f+/-%4.2f|" score (/ (- high low) 2.0)) 586 (format "|%3.1f+/-%4.2f|" score (/ (- high low) 2.0))
596 (bbb-fmt-prediction-num score))) 587 (bbb-fmt-prediction-num score)))
597 588
598 (defun bbb-fmt-prediction-bar (rate-string score) 589 (defun bbb-fmt-prediction-bar (rate-string score)
599 (let* ((i 1) 590 (let* ((i 1)
600 (step (/ grplens-rating-range (- grplens-predstringsize 4))) 591 (step (/ grplens-rating-range (- grplens-predstringsize 4)))
601 (half-step (/ step 2)) 592 (half-step (/ step 2))
602 (loc (- grplens-minrating half-step))) 593 (loc (- grplens-minrating half-step)))
603 (while (< i (- grplens-predstringsize 2)) 594 (while (< i (- grplens-predstringsize 2))
604 (if (> score loc) 595 (if (> score loc)
605 (aset rate-string i ?#) 596 (aset rate-string i ?#)
606 (aset rate-string i ? )) 597 (aset rate-string i ?\ ))
607 (setq i (+ i 1)) 598 (setq i (+ i 1))
608 (setq loc (+ loc step))) 599 (setq loc (+ loc step)))
609 ) 600 )
610 rate-string) 601 rate-string)
611 602
614 605
615 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 606 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
616 ;;;; Put Ratings 607 ;;;; Put Ratings
617 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 608 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
618 609
619 ;; The message-id for the current article can be found in
620 ;; (aref gnus-current-headers (nth 1 (assoc "message-id" gnus-header-index)))
621
622 (defun bbb-put-ratings () 610 (defun bbb-put-ratings ()
623 (if (and grouplens-rating-alist 611 (if (and grouplens-bbb-token
612 grouplens-rating-alist
624 (member gnus-newsgroup-name grouplens-newsgroups)) 613 (member gnus-newsgroup-name grouplens-newsgroups))
625 (let ((bbb-process (bbb-connect-to-bbbd grouplens-bbb-host 614 (let ((bbb-process (bbb-connect-to-bbbd grouplens-bbb-host
626 grouplens-bbb-port)) 615 grouplens-bbb-port))
627 (rate-command (bbb-build-rate-command grouplens-rating-alist))) 616 (rate-command (bbb-build-rate-command grouplens-rating-alist)))
628 (if bbb-process 617 (if bbb-process
629 (save-excursion 618 (save-excursion
630 (set-buffer (process-buffer bbb-process)) 619 (set-buffer (process-buffer bbb-process))
631 (gnus-message 5 "Sending Ratings...") 620 (gnus-message 5 "Sending Ratings...")
638 (gnus-message 5 "Sending Ratings...Done")) 627 (gnus-message 5 "Sending Ratings...Done"))
639 (gnus-message 3 "No BBB connection"))) 628 (gnus-message 3 "No BBB connection")))
640 (setq grouplens-rating-alist nil))) 629 (setq grouplens-rating-alist nil)))
641 630
642 (defun bbb-build-rate-command (rate-alist) 631 (defun bbb-build-rate-command (rate-alist)
643 (let (this 632 (concat "putratings " grouplens-bbb-token " " grouplens-current-group " \r\n"
644 (cmd (concat "putratings " grouplens-bbb-token 633 (mapconcat '(lambda (this) ; form (mid . (score . time))
645 " " grouplens-current-group " \r\n"))) 634 (concat (car this)
646 (while rate-alist 635 " :rating=" (cadr this) ".00"
647 (setq this (car rate-alist) 636 " :time=" (cddr this)))
648 cmd (concat cmd (car this) " :rating=" (cadr this) ".00" 637 rate-alist "\r\n")
649 " :time=" (cddr this) "\r\n") 638 "\r\n.\r\n"))
650 rate-alist (cdr rate-alist)))
651 (concat cmd ".\r\n")))
652 639
653 ;; Interactive rating functions. 640 ;; Interactive rating functions.
654 (defun bbb-summary-rate-article (rating &optional midin) 641 (defun bbb-summary-rate-article (rating &optional midin)
655 (interactive "nRating: ") 642 (interactive "nRating: ")
656 (when (member gnus-newsgroup-name grouplens-newsgroups) 643 (when (member gnus-newsgroup-name grouplens-newsgroups)
657 (let ((mid (or midin (bbb-get-current-id)))) 644 (let ((mid (or midin (bbb-get-current-id))))
658 (if (and rating 645 (if (and rating
659 (>= rating grplens-minrating) 646 (>= rating grplens-minrating)
660 (<= rating grplens-maxrating) 647 (<= rating grplens-maxrating)
661 mid) 648 mid)
662 (let ((oldrating (assoc mid grouplens-rating-alist))) 649 (let ((oldrating (assoc mid grouplens-rating-alist)))
663 (if oldrating 650 (if oldrating
664 (setcdr oldrating (cons rating 0)) 651 (setcdr oldrating (cons rating 0))
665 (push `(,mid . (,rating . 0)) grouplens-rating-alist)) 652 (push `(,mid . (,rating . 0)) grouplens-rating-alist))
666 (gnus-summary-mark-article nil (int-to-string rating))) 653 (gnus-summary-mark-article nil (int-to-string rating)))
667 (gnus-message 3 "Invalid rating"))))) 654 (gnus-message 3 "Invalid rating")))))
668 655
669 (defun grouplens-next-unread-article (rating) 656 (defun grouplens-next-unread-article (rating)
670 "Select unread article after current one." 657 "Select unread article after current one."
671 (interactive "P") 658 (interactive "P")
672 (if rating (bbb-summary-rate-article rating)) 659 (when rating
660 (bbb-summary-rate-article rating))
673 (gnus-summary-next-unread-article)) 661 (gnus-summary-next-unread-article))
674 662
675 (defun grouplens-best-unread-article (rating) 663 (defun grouplens-best-unread-article (rating)
676 "Select unread article after current one." 664 "Select unread article after current one."
677 (interactive "P") 665 (interactive "P")
678 (if rating (bbb-summary-rate-article rating)) 666 (when rating
667 (bbb-summary-rate-article rating))
679 (gnus-summary-best-unread-article)) 668 (gnus-summary-best-unread-article))
680 669
681 (defun grouplens-summary-catchup-and-exit (rating) 670 (defun grouplens-summary-catchup-and-exit (rating)
682 "Mark all articles not marked as unread in this newsgroup as read, 671 "Mark all articles not marked as unread in this newsgroup as read,
683 then exit. If prefix argument ALL is non-nil, all articles are 672 then exit. If prefix argument ALL is non-nil, all articles are
684 marked as read." 673 marked as read."
685 (interactive "P") 674 (interactive "P")
686 (if rating 675 (when rating
687 (bbb-summary-rate-article rating)) 676 (bbb-summary-rate-article rating))
688 (if (numberp rating) 677 (if (numberp rating)
689 (gnus-summary-catchup-and-exit) 678 (gnus-summary-catchup-and-exit)
690 (gnus-summary-catchup-and-exit rating))) 679 (gnus-summary-catchup-and-exit rating)))
691 680
692 (defun grouplens-score-thread (score) 681 (defun grouplens-score-thread (score)
693 "Raise the score of the articles in the current thread with SCORE." 682 "Raise the score of the articles in the current thread with SCORE."
694 (interactive "nRating: ") 683 (interactive "nRating: ")
695 (let (e) 684 (let (e)
696 (save-excursion 685 (save-excursion
697 (let ((articles (gnus-summary-articles-in-thread))) 686 (let ((articles (gnus-summary-articles-in-thread))
698 (while articles 687 article)
699 (gnus-summary-goto-subject (car articles)) 688 (while (setq article (pop articles))
689 (gnus-summary-goto-subject article)
700 (gnus-set-global-variables) 690 (gnus-set-global-variables)
701 (bbb-summary-rate-article score 691 (bbb-summary-rate-article score
702 (mail-header-id 692 (mail-header-id
703 (gnus-summary-article-header 693 (gnus-summary-article-header article)))))
704 (car articles))))
705 (setq articles (cdr articles))))
706 (setq e (point))) 694 (setq e (point)))
707 (let ((gnus-summary-check-current t)) 695 (let ((gnus-summary-check-current t))
708 (or (zerop (gnus-summary-next-subject 1 t)) 696 (or (zerop (gnus-summary-next-subject 1 t))
709 (goto-char e)))) 697 (goto-char e))))
710 (gnus-summary-recenter) 698 (gnus-summary-recenter)
711 (gnus-summary-position-point) 699 (gnus-summary-position-point)
712 (gnus-set-mode-line 'summary)) 700 (gnus-set-mode-line 'summary))
713 701
702 (defun bbb-exit-group ()
703 (bbb-put-ratings)
704 (bbb-renew-hash-table))
714 705
715 (defun bbb-get-current-id () 706 (defun bbb-get-current-id ()
716 (if gnus-current-headers 707 (if gnus-current-headers
717 (aref gnus-current-headers 708 (mail-header-id gnus-current-headers)
718 (nth 1 (assoc "message-id" gnus-header-index)))
719 (gnus-message 3 "You must select an article before you rate it"))) 709 (gnus-message 3 "You must select an article before you rate it")))
720 710
721 (defun bbb-grouplens-group-p (group) 711 (defun bbb-grouplens-group-p (group)
722 "Say whether GROUP is a GroupLens group." 712 "Say whether GROUP is a GroupLens group."
723 (if (member group grouplens-newsgroups) " (GroupLens Enhanced)" "")) 713 (if (member group grouplens-newsgroups) " (GroupLens Enhanced)" ""))
733 (defun grouplens-elapsed-time () 723 (defun grouplens-elapsed-time ()
734 (let ((et (bbb-time-float (current-time)))) 724 (let ((et (bbb-time-float (current-time))))
735 (- et (bbb-time-float grouplens-current-starting-time)))) 725 (- et (bbb-time-float grouplens-current-starting-time))))
736 726
737 (defun bbb-time-float (timeval) 727 (defun bbb-time-float (timeval)
738 (+ (* (car timeval) 65536) 728 (+ (* (car timeval) 65536)
739 (cadr timeval))) 729 (cadr timeval)))
740 730
741 (defun grouplens-do-time () 731 (defun grouplens-do-time ()
742 (when (member gnus-newsgroup-name grouplens-newsgroups) 732 (when (member gnus-newsgroup-name grouplens-newsgroups)
743 (when grouplens-previous-article 733 (when grouplens-previous-article
744 (let ((elapsed-time (grouplens-elapsed-time)) 734 (let ((elapsed-time (grouplens-elapsed-time))
753 743
754 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 744 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
755 ;; BUG REPORTING 745 ;; BUG REPORTING
756 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 746 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
757 747
758 (defconst gnus-gl-version "gnus-gl.el 2.12") 748 (defconst gnus-gl-version "gnus-gl.el 2.50")
759 (defconst gnus-gl-maintainer-address "grouplens-bug@cs.umn.edu") 749 (defconst gnus-gl-maintainer-address "grouplens-bug@cs.umn.edu")
760 (defun gnus-gl-submit-bug-report () 750 (defun gnus-gl-submit-bug-report ()
761 "Submit via mail a bug report on gnus-gl" 751 "Submit via mail a bug report on gnus-gl"
762 (interactive) 752 (interactive)
763 (require 'reporter) 753 (require 'reporter)
768 'grouplens-bbb-port 758 'grouplens-bbb-port
769 'grouplens-newsgroups 759 'grouplens-newsgroups
770 'grouplens-bbb-token 760 'grouplens-bbb-token
771 'grouplens-bbb-process 761 'grouplens-bbb-process
772 'grouplens-current-group 762 'grouplens-current-group
773 'grouplens-previous-article 763 'grouplens-previous-article)
774 'grouplens-mid-list
775 'bbb-alist)
776 nil 764 nil
777 'gnus-gl-get-trace)) 765 'gnus-gl-get-trace))
778 766
779 (defun gnus-gl-get-trace () 767 (defun gnus-gl-get-trace ()
780 "Insert the contents of the BBBD trace buffer" 768 "Insert the contents of the BBBD trace buffer"
781 (if grouplens-bbb-buffer (insert-buffer grouplens-bbb-buffer))) 769 (when grouplens-bbb-buffer
782 770 (insert-buffer grouplens-bbb-buffer)))
783 ;;; 771
784 ;;; Additions to make gnus-grouplens-mode Warning Warning!! 772 ;;
785 ;;; This version of the gnus-grouplens-mode does 773 ;; GroupLens minor mode
786 ;;; not work with gnus-5.x. The "old" way of 774 ;;
787 ;;; setting up GroupLens still works however. 775
788 ;;;
789 (defvar gnus-grouplens-mode nil 776 (defvar gnus-grouplens-mode nil
790 "Minor mode for providing a GroupLens interface in Gnus summary buffers.") 777 "Minor mode for providing a GroupLens interface in Gnus summary buffers.")
791 778
792 (defvar gnus-grouplens-mode-map nil) 779 (defvar gnus-grouplens-mode-map nil)
793 780
821 (make-local-variable 'gnus-grouplens-mode) 808 (make-local-variable 'gnus-grouplens-mode)
822 (setq gnus-grouplens-mode 809 (setq gnus-grouplens-mode
823 (if (null arg) (not gnus-grouplens-mode) 810 (if (null arg) (not gnus-grouplens-mode)
824 (> (prefix-numeric-value arg) 0))) 811 (> (prefix-numeric-value arg) 0)))
825 (when gnus-grouplens-mode 812 (when gnus-grouplens-mode
826 (if (not (fboundp 'make-local-hook)) 813 (make-local-hook 'gnus-select-article-hook)
827 (add-hook 'gnus-select-article-hook 'grouplens-do-time) 814 (gnus-add-hook 'gnus-select-article-hook 'grouplens-do-time nil 'local)
828 (make-local-hook 'gnus-select-article-hook) 815 (make-local-hook 'gnus-exit-group-hook)
829 (add-hook 'gnus-select-article-hook 'grouplens-do-time nil 'local)) 816 (gnus-add-hook 'gnus-exit-group-hook 'bbb-exit-group nil 'local)
830 (if (not (fboundp 'make-local-hook))
831 (add-hook 'gnus-exit-group-hook 'bbb-put-ratings)
832 (make-local-hook 'gnus-exit-group-hook)
833 (add-hook 'gnus-exit-group-hook 'bbb-put-ratings nil 'local))
834 (make-local-variable 'gnus-score-find-score-files-function) 817 (make-local-variable 'gnus-score-find-score-files-function)
835 (cond ((eq gnus-grouplens-override-scoring 'combine) 818
836 ;; either add bbb-buld-mid-scores-alist to a list 819 (cond
837 ;; or make a list 820 ((eq gnus-grouplens-override-scoring 'combine)
838 (if (listp gnus-score-find-score-files-function) 821 ;; either add bbb-buld-mid-scores-alist to a list
839 (setq gnus-score-find-score-files-function 822 ;; or make a list
840 (append 'bbb-build-mid-scores-alist 823 (if (listp gnus-score-find-score-files-function)
841 gnus-score-find-score-files-function )) 824 (setq gnus-score-find-score-files-function
842 (setq gnus-score-find-score-files-function 825 (append 'bbb-build-mid-scores-alist
843 (list gnus-score-find-score-files-function 826 gnus-score-find-score-files-function))
844 'bbb-build-mid-scores-alist)))) 827 (setq gnus-score-find-score-files-function
845 ;; leave the gnus-score-find-score-files variable alone 828 (list gnus-score-find-score-files-function
846 ((eq gnus-grouplens-override-scoring 'separate) 829 'bbb-build-mid-scores-alist))))
847 (add-hook 'gnus-select-group-hook 830 ;; leave the gnus-score-find-score-files variable alone
848 '(lambda() 831 ((eq gnus-grouplens-override-scoring 'separate)
849 (bbb-build-mid-scores-alist gnus-newsgroup-name)))) 832 (add-hook 'gnus-select-group-hook
850 ;; default is to override 833 (lambda ()
851 (t (setq gnus-score-find-score-files-function 834 (bbb-get-predictions (bbb-get-all-mids)
852 'bbb-build-mid-scores-alist))) 835 gnus-newsgroup-name))))
836 ;; default is to override
837 (t
838 (setq gnus-score-find-score-files-function
839 'bbb-build-mid-scores-alist)))
840
841 ;; Change how summary lines look
853 (make-local-variable 'gnus-summary-line-format) 842 (make-local-variable 'gnus-summary-line-format)
854 (setq gnus-summary-line-format
855 gnus-summary-grouplens-line-format)
856 (make-local-variable 'gnus-summary-line-format-spec) 843 (make-local-variable 'gnus-summary-line-format-spec)
844 (setq gnus-summary-line-format gnus-summary-grouplens-line-format)
857 (setq gnus-summary-line-format-spec nil) 845 (setq gnus-summary-line-format-spec nil)
846 (gnus-update-format-specifications nil 'summary)
847 (gnus-update-summary-mark-positions)
858 848
859 ;; Set up the menu. 849 ;; Set up the menu.
860 (when (and menu-bar-mode 850 (when (and menu-bar-mode
861 (gnus-visual-p 'grouplens-menu 'menu)) 851 (gnus-visual-p 'grouplens-menu 'menu))
862 (gnus-grouplens-make-menu-bar)) 852 (gnus-grouplens-make-menu-bar))