Mercurial > hg > xemacs-beta
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)) |