Mercurial > hg > xemacs
comparison lucid/my-news.el @ 0:107d592c5f4a
DICE versions, used by pers/common, recursive, I think/hope
| author | Henry S. Thompson <ht@inf.ed.ac.uk> |
|---|---|
| date | Mon, 08 Feb 2021 11:44:37 +0000 |
| parents | |
| children | 0a81352bd7d0 |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:107d592c5f4a |
|---|---|
| 1 (load "gnus" nil t) | |
| 2 ;(require 'spam) | |
| 3 (require 'cl) | |
| 4 ;(spam-initialize) | |
| 5 (setq | |
| 6 gnus-select-method '(nntp "usenet.inf.ed.ac.uk") | |
| 7 gnus-post-method '(nntp "usenet.inf.ed.ac.uk") | |
| 8 gnus-nntp-server nil ; override local default | |
| 9 ) | |
| 10 | |
| 11 (setq gnus-use-scoring nil ; not used yet | |
| 12 gnus-summary-gather-subject-limit nil | |
| 13 gnus-thread-sort-functions | |
| 14 '(gnus-thread-sort-by-number gnus-thread-sort-by-simpl-subject) | |
| 15 gnus-summary-line-format "%U%R%5N%I%(%[%4L: %-12,12A%]%) %s\n" | |
| 16 gnus-summary-make-false-root 'none | |
| 17 gnus-mime-display-multipart-related-as-mixed t | |
| 18 gnus-simplify-subject-regexp "^\\(re[:;.]\\| \\|fwd:\\)*") | |
| 19 | |
| 20 (defsubst gnus-trim-simplify-subject (text) | |
| 21 (if (string-match gnus-simplify-subject-regexp text) | |
| 22 (substring text (match-end 0)) | |
| 23 text)) | |
| 24 | |
| 25 (defun gnus-thread-sort-by-simpl-subject (h1 h2) | |
| 26 "sort by slightly simplified subject" | |
| 27 ; (message (format "%s:%s %s:%s" (mail-header-number (gnus-thread-header h1))(mail-header-subject (gnus-thread-header h1))(mail-header-number (gnus-thread-header h2))(mail-header-subject (gnus-thread-header h2)))) | |
| 28 (let ((case-fold-search t)) | |
| 29 (let ((result | |
| 30 (string-lessp | |
| 31 (downcase (gnus-trim-simplify-subject (mail-header-subject | |
| 32 (gnus-thread-header h1)))) | |
| 33 (downcase (gnus-trim-simplify-subject (mail-header-subject | |
| 34 (gnus-thread-header h2))))))) | |
| 35 ; (message (format " %s\n" result)) | |
| 36 result))) | |
| 37 | |
| 38 | |
| 39 ;; Database stuff | |
| 40 | |
| 41 | |
| 42 (defun open-white () | |
| 43 (setq whitelist-db (open-database "/disk/scratch/mail/white" 'berkeley-db))) | |
| 44 | |
| 45 (defun save-white () | |
| 46 (close-database whitelist-db) | |
| 47 (open-white)) | |
| 48 | |
| 49 (defun open-ad () | |
| 50 (setq adlist-db (open-database "/disk/scratch/mail/ad" 'berkeley-db))) | |
| 51 | |
| 52 (defun save-ad () | |
| 53 (close-database adlist-db) | |
| 54 (open-ad)) | |
| 55 | |
| 56 (defun open-quaker () | |
| 57 (setq quaker-db (open-database "/disk/scratch/mail/quaker" 'berkeley-db))) | |
| 58 (defun save-quaker () | |
| 59 (close-database quaker-db) | |
| 60 (open-quaker)) | |
| 61 | |
| 62 (defvar database-names '(whitelist-db adlist-db quaker-db) "sic") | |
| 63 | |
| 64 (defun db-status (&optional name) | |
| 65 "Check on the whereabouts of a name" | |
| 66 (interactive) | |
| 67 (let ((addr | |
| 68 (or name | |
| 69 (progn | |
| 70 (gnus-summary-goto-article (gnus-summary-article-number)) | |
| 71 (get-canonical-from-addr (get-current-from-components))))) | |
| 72 res) | |
| 73 (dolist (dbn database-names) | |
| 74 (if (get-database addr (eval dbn)) | |
| 75 (setq res (cons dbn res)))) | |
| 76 (if name | |
| 77 res | |
| 78 (message "%s" res)))) | |
| 79 | |
| 80 (defun add-white (&optional addToBBDB) | |
| 81 (interactive "P") | |
| 82 (gnus-summary-goto-article (gnus-summary-article-number)) | |
| 83 (let* ((components (get-current-from-components)) | |
| 84 (addr (get-canonical-from-addr components))) | |
| 85 (if (new-white addr) | |
| 86 (save-white)) | |
| 87 (if addToBBDB | |
| 88 (let ((bbdb-no-duplicates-p t)) | |
| 89 (bbdb-create-internal (car components) nil (cadr components) | |
| 90 nil nil nil))))) | |
| 91 | |
| 92 (defun add-ad () | |
| 93 (interactive) | |
| 94 (gnus-summary-goto-article (gnus-summary-article-number)) | |
| 95 (let ((addr (get-current-from-addr))) | |
| 96 (if (or (not (get-database addr whitelist-db)) | |
| 97 (yes-or-no-p "Already white, really convert to ad?")) | |
| 98 (if (new-ad addr) | |
| 99 (save-ad))))) | |
| 100 | |
| 101 (defun add-quaker() | |
| 102 (interactive) | |
| 103 (let ((addr (get-addr-before-point))) | |
| 104 (when (new-quaker addr) | |
| 105 (save-quaker)) | |
| 106 (quaker-sig-maybe))) | |
| 107 | |
| 108 (defun quaker-sig-if-to-quaker () | |
| 109 (let ((message-options)) | |
| 110 (save-excursion (message-options-set-recipient)) | |
| 111 (let* ((recipStr (message-options-get 'message-recipients)) | |
| 112 (recips (split-string (downcase recipStr) | |
| 113 ",[ \f\t\n\r\v]+" t))) | |
| 114 (while (and recips | |
| 115 (not (quaker-sig-if-quaker-1 (car recips)))) | |
| 116 (setq recips (cdr recips)))))) | |
| 117 | |
| 118 (defun quaker-sig-if-quaker () | |
| 119 (quaker-sig-if-quaker-1 (get-addr-before-point))) | |
| 120 | |
| 121 (defun quaker-sig-if-quaker-1 (addr) | |
| 122 (if (get-database addr quaker-db) | |
| 123 (progn (quaker-sig-maybe) | |
| 124 t))) | |
| 125 | |
| 126 (defun quaker-sig-maybe () | |
| 127 (save-excursion | |
| 128 (goto-char (point-max)) | |
| 129 (search-backward "\n-- \n") | |
| 130 (when (looking-at "\n-- \n Henry") | |
| 131 (forward-char 5) | |
| 132 (kill-entire-line 5) | |
| 133 (insert-file "/afs/inf.ed.ac.uk/user/h/ht/.quaker-sig")))) | |
| 134 | |
| 135 (defun kill-white () | |
| 136 (interactive) | |
| 137 (gnus-summary-goto-article (gnus-summary-article-number)) | |
| 138 (let ((addr (downcase (get-current-from-addr)))) | |
| 139 (rem-white addr))) | |
| 140 | |
| 141 (defun kill-ad () | |
| 142 (interactive) | |
| 143 (gnus-summary-goto-article (gnus-summary-article-number)) | |
| 144 (let ((addr (downcase (get-current-from-addr)))) | |
| 145 (rem-ad addr))) | |
| 146 | |
| 147 (defun get-from-gnus-addr () | |
| 148 (get-from-addr (gnus-fetch-field "From"))) | |
| 149 | |
| 150 (defun get-from-addr (addr) | |
| 151 (get-canonical-from-addr (gnus-extract-address-components addr))) | |
| 152 | |
| 153 (defun get-canonical-from-addr (components) | |
| 154 (downcase (cadr components))) | |
| 155 | |
| 156 (defun get-current-from-addr () | |
| 157 (with-current-buffer gnus-article-buffer | |
| 158 (get-from-gnus-addr))) | |
| 159 | |
| 160 (defun get-current-from-components () | |
| 161 (with-current-buffer gnus-article-buffer | |
| 162 (gnus-extract-address-components (gnus-fetch-field "From")))) | |
| 163 | |
| 164 (defun get-addr-before-point () | |
| 165 (let ((cur (point))) | |
| 166 (save-excursion | |
| 167 (get-from-addr (buffer-substring (+ (search-backward " ") 1) cur))) | |
| 168 )) | |
| 169 | |
| 170 (defun blacken-and-delete (group) | |
| 171 ;; mis-named now | |
| 172 ;; this is part of the expiry processing for xxxSPAM groups, and | |
| 173 ;; actually whitens the from addresses of #-marked articles | |
| 174 ;; The return value is crucial (and crucially outside of the scope of the if) | |
| 175 (if (memq number | |
| 176 (with-current-buffer gnus-summary-buffer | |
| 177 gnus-newsgroup-processable)) | |
| 178 (let ((addr (get-from-gnus-addr))) | |
| 179 (new-white addr))) | |
| 180 'delete) | |
| 181 | |
| 182 (defun unwhiten-and-delete (group) | |
| 183 ;; unused except in stale groups -- usable as an expiry | |
| 184 (if (memq number | |
| 185 (with-current-buffer gnus-summary-buffer | |
| 186 gnus-newsgroup-processable)) | |
| 187 (let ((addr (get-from-gnus-addr))) | |
| 188 (remove-database addr whitelist-db))) | |
| 189 'delete) | |
| 190 | |
| 191 (defun known-black (list) | |
| 192 (if (get-database (get-from-gnus-addr) blacklist-db) | |
| 193 list)) | |
| 194 | |
| 195 (defun white-spam (list) | |
| 196 (if (or (equal (get-database (get-from-gnus-addr) whitelist-db) "t") | |
| 197 (let ((case-fold-search t) | |
| 198 (subj (gnus-fetch-field "Subject")) | |
| 199 (from (get-from-gnus-addr))) | |
| 200 (or | |
| 201 (and subj (string-match white-subjects subj)) | |
| 202 (and from | |
| 203 (let ((fromDom (substring from (+ 1 (search "@" from))))) | |
| 204 (and fromDom (member fromDom white-domains))))))) | |
| 205 list)) | |
| 206 | |
| 207 (defun ad-spam (list) | |
| 208 (if (let ((from (get-from-gnus-addr))) | |
| 209 (or | |
| 210 (equal (get-database from adlist-db) "t") | |
| 211 (and from | |
| 212 (let ((fromDom (substring from (+ 1 (search "@" from))))) | |
| 213 (and fromDom (member fromDom ad-domains)))) | |
| 214 )) | |
| 215 list)) | |
| 216 | |
| 217 (defun bogoNote (group) | |
| 218 (if (memq number | |
| 219 (with-current-buffer gnus-summary-buffer | |
| 220 gnus-newsgroup-processable)) | |
| 221 (let ((addr (get-from-gnus-addr))) | |
| 222 (new-white addr))) | |
| 223 (shell-command-on-region (point-min) (point-max) | |
| 224 "/afs/inf.ed.ac.uk/user/h/ht/share/bin/local/makeBogo") | |
| 225 'delete) | |
| 226 | |
| 227 (defun whiten-recip () | |
| 228 ;;; a hook for outgoing mail | |
| 229 (let* ((recips (message-options-get 'message-recipients)) | |
| 230 (res (mapcar (function new-white) | |
| 231 (split-string (downcase recips) | |
| 232 ",[ \f\t\n\r\v]*" t)))) | |
| 233 (while (and res (not (car res))) | |
| 234 (setq res (cdr res))) | |
| 235 (if res (save-white)))) | |
| 236 | |
| 237 | |
| 238 (defun new-white (addr) | |
| 239 (if (get-database addr whitelist-db) | |
| 240 nil | |
| 241 (put-database addr "t" whitelist-db) | |
| 242 t)) | |
| 243 | |
| 244 (defun new-ad (addr) | |
| 245 (if (get-database addr adlist-db) | |
| 246 nil | |
| 247 (put-database addr "t" adlist-db) | |
| 248 t)) | |
| 249 | |
| 250 (defun rem-ad (addr) | |
| 251 (remove-database addr adlist-db) | |
| 252 (save-ad)) | |
| 253 | |
| 254 (defun new-quaker (addr) | |
| 255 (if (get-database addr quaker-db) | |
| 256 nil | |
| 257 (put-database addr "t" quaker-db) | |
| 258 t)) | |
| 259 | |
| 260 (defun rem-white (addr) | |
| 261 (remove-database (downcase addr) whitelist-db) | |
| 262 (save-white)) | |
| 263 | |
| 264 (defun bogoOK (group) | |
| 265 (shell-command-on-region (point-min) (point-max) | |
| 266 "/afs/inf.ed.ac.uk/user/h/ht/share/bin/local/makeNonBogo") | |
| 267 'delete) | |
| 268 | |
| 269 (defun del-dups () | |
| 270 (interactive) | |
| 271 (gnus-summary-sort-by-subject) | |
| 272 (gnus-summary-clear-mark-forward 1) | |
| 273 (goto-char (point-min)) | |
| 274 (let ((pos)) | |
| 275 (while (setq pos (search-forward "] " nil t)) | |
| 276 (end-of-line) | |
| 277 (let ((subj (buffer-substring pos (point)))) | |
| 278 (unless (equal subj "") | |
| 279 (let ((target (if (< (length subj) 26) | |
| 280 (concat "] " subj "\n") | |
| 281 (concat "] " (substring subj 0 25)))) | |
| 282 (done 0) | |
| 283 (case-fold-search nil)) | |
| 284 (while (and (= done 0) | |
| 285 (search-forward target nil t)) | |
| 286 (forward-char -3) | |
| 287 (setq done (gnus-summary-mark-as-read-forward 1)))))))) | |
| 288 (gnus-summary-limit-to-unread) | |
| 289 (gnus-summary-sort-by-original)) | |
| 290 | |
| 291 (defun mark-and-mark (n) | |
| 292 (interactive "p") | |
| 293 (while (>= n 1) | |
| 294 (gnus-summary-mark-as-read) | |
| 295 (gnus-summary-mark-as-processable 1) | |
| 296 (setq n (- n 1)))) | |
| 297 | |
| 298 (defun split-on-whole-field (field pat list) | |
| 299 (goto-char (point-max)) | |
| 300 (let ((hit (assq pat wsp-cache)) | |
| 301 rpat) | |
| 302 (if hit | |
| 303 (setq rpat (cdr hit)) | |
| 304 (setq rpat | |
| 305 (concat "^" | |
| 306 field | |
| 307 ":\\s-*" | |
| 308 (if (stringp pat) | |
| 309 pat | |
| 310 (cdr (assq pat | |
| 311 nnmail-split-abbrev-alist))) | |
| 312 "$")) | |
| 313 (setq wsp-cache (cons (cons pat rpat) wsp-cache))) | |
| 314 (if (re-search-backward rpat nil t) | |
| 315 list))) | |
| 316 | |
| 317 (defun ht-gnus-summary-delete-forward () | |
| 318 "REAL delete for nnmail gnus" | |
| 319 (interactive) | |
| 320 (gnus-summary-delete-article) | |
| 321 (gnus-summary-next-unread-article)) | |
| 322 | |
| 323 ;; run the first time we make a summary window | |
| 324 (defun gnus-summary-mode-fun1 () | |
| 325 "install ht's mods" | |
| 326 (define-key gnus-summary-mode-map "D" 'ht-gnus-summary-delete-forward) | |
| 327 (define-key gnus-summary-mode-map "~" 'mark-and-mark) | |
| 328 (define-key gnus-summary-mode-map "\M-d" 'gnus-edit-and-move-to-diary) | |
| 329 (define-key gnus-summary-mode-map "\M-e" 'gnus-extract-attachment) | |
| 330 (define-key gnus-summary-mode-map "\M-w" 'add-white) | |
| 331 (define-key gnus-summary-mode-map [(control meta w)] 'copy-region-to-kill) | |
| 332 (define-key gnus-summary-mode-map "\M-h" 'showMPAhtml) | |
| 333 ;(define-key gnus-summary-mode-map [(control meta w)] 'kill-white) | |
| 334 (define-key gnus-summary-mode-map "\M-a" 'add-ad) | |
| 335 (define-key gnus-summary-mode-map "\M-n" 'ht-next-unseen-maybe) | |
| 336 (define-key gnus-summary-mode-map "\M-c" 'ht-catchup-and-next-unseen) | |
| 337 (define-key gnus-summary-mime-map "O" 'ht-article-save-parts) | |
| 338 (define-key gnus-summary-backend-map "M" 'ht-move-to-pers) | |
| 339 (remove-hook 'gnus-summary-mode-hook 'gnus-summary-mode-fun1)) | |
| 340 | |
| 341 (defun message-mode-fun1 () | |
| 342 (define-key message-mode-map [(control meta q)] 'add-quaker) | |
| 343 (remove-hook 'message-mode-hook 'message-mode-fun1)) | |
| 344 | |
| 345 (defvar ht-gnus-just-read nil) | |
| 346 | |
| 347 (defun ht-catchup-and-next-unseen () | |
| 348 (interactive) | |
| 349 (when (gnus-summary-catchup nil t nil 'fast) | |
| 350 (gnus-summary-exit) | |
| 351 (previous-line 1) | |
| 352 (ht-next-with-unseen 1))) | |
| 353 | |
| 354 (defun ht-next-unseen-maybe (n) | |
| 355 (interactive "p") | |
| 356 (cond | |
| 357 ((eq (gnus-summary-next-unread-subject n) n) | |
| 358 (gnus-summary-exit) | |
| 359 (previous-line 1) | |
| 360 (if (ht-next-with-unseen n) | |
| 361 (ht-read-group-unseen-only))))) | |
| 362 | |
| 363 (defun ht-gnus-pers-refresh (n) | |
| 364 (interactive "p") | |
| 365 (let ((gn (concat "nnml+ht:pers-" | |
| 366 (format-time-string "%Y-%m" (current-time))))) | |
| 367 (gnus-group-get-new-news) | |
| 368 (let ((nn (gnus-number-of-unseen-articles-in-group gn))) | |
| 369 (gnus-group-goto-group gn) | |
| 370 (cond | |
| 371 ((> nn 0) | |
| 372 (gnus-group-read-group nn)) | |
| 373 ((> n 1) | |
| 374 (let ((gnus-auto-select-subject | |
| 375 (lambda () | |
| 376 (goto-char (point-max)) | |
| 377 (previous-line 1)))) | |
| 378 (gnus-group-read-group nil t))) | |
| 379 (t (goto-char (point-min)) | |
| 380 (ht-next-with-unseen 1)))) | |
| 381 (message "%s" ht-gnus-just-read)) | |
| 382 ) | |
| 383 | |
| 384 (defun no-select () | |
| 385 (if (member gnus-newsgroup-name no-select-groups) | |
| 386 (progn (make-variable-buffer-local 'gnus-auto-select-first) | |
| 387 (setq gnus-auto-select-first nil)))) | |
| 388 | |
| 389 (defun showMPAhtml () | |
| 390 "Show the text/html parts of an multipart/alternative message using lynx" | |
| 391 (interactive) | |
| 392 (gnus-summary-select-article) | |
| 393 (with-current-buffer gnus-original-article-buffer | |
| 394 (shell-command-on-region (point-min) (point-max) "/afs/inf.ed.ac.uk/user/h/ht/share/bin/showMPA.sh") | |
| 395 ) | |
| 396 ) | |
| 397 | |
| 398 | |
| 399 ;; run the first time we make a group window | |
| 400 (defun gnus-group-mode-fun1 () | |
| 401 "install ht's mods" | |
| 402 (require 'gnus-msg) | |
| 403 (define-key gnus-group-mode-map "\M-\C-g" 'ht-gnus-pers-refresh) | |
| 404 (define-key gnus-group-mode-map "\M-n" 'ht-next-with-unseen) | |
| 405 (define-key gnus-group-mode-map "\M-p" 'ht-previous-with-unseen) | |
| 406 (define-key gnus-group-mode-map "\M- " 'ht-read-group-unseen-only) | |
| 407 (define-key gnus-send-bounce-map "R" 'resend-to-schemadev) | |
| 408 (define-key gnus-send-bounce-map "x" 'flush-all-nogoods) | |
| 409 (remove-hook 'gnus-group-mode-hook 'gnus-group-mode-fun1)) | |
| 410 | |
| 411 (defun flush-all-nogoods () | |
| 412 (interactive) | |
| 413 (while (re-search-forward | |
| 414 "] \\(\\(Returned\\|\\([Uu]n\\|[Nn]on-?\\)deliver\\(able\\|ed\\)\\)\\( [Mm]ail\\|:?\\)\\|DELIVERY FAILURE\\|Delivery \\(Notification: Delivery has failed\\|Status Notification .\\(Failure\\|Delay\\).\\)\\|failure \\(notice\\|delivery\\)\\)" | |
| 415 nil t) | |
| 416 (gnus-summary-mark-as-read) | |
| 417 (end-of-line))) | |
| 418 | |
| 419 (defun gnus-user-format-function-t (header) | |
| 420 "display the to field (for archive messages)" | |
| 421 (let ((n (mail-header-number header))) | |
| 422 (with-current-buffer nntp-server-buffer | |
| 423 (save-excursion | |
| 424 (save-restriction | |
| 425 (let ((inhibit-point-motion-hooks t)) | |
| 426 (goto-char (point-min)) | |
| 427 (let ((beg (search-forward (format " %d Article retrieved." n))) | |
| 428 (end (search-forward "\n.\n"))) | |
| 429 (narrow-to-region beg end) | |
| 430 (goto-char beg) | |
| 431 (message-fetch-field "To")))))))) | |
| 432 | |
| 433 (defun gnus-extract-attachment () | |
| 434 "extract attachments from a multi-part mime message" | |
| 435 (interactive) | |
| 436 (let ((sm gnus-show-mime)) | |
| 437 (if sm | |
| 438 (progn (setq gnus-show-mime nil) | |
| 439 (gnus-summary-select-article t 'force)) | |
| 440 ) | |
| 441 (gnus-summary-show-all-headers) | |
| 442 (with-current-buffer gnus-article-buffer | |
| 443 (save-excursion | |
| 444 (save-restriction | |
| 445 (mime/viewer-mode) | |
| 446 (delete-other-windows) | |
| 447 (let ((pt 0)) | |
| 448 (while (progn | |
| 449 (mime-viewer/next-content) | |
| 450 (and | |
| 451 (equal "*Preview-*Article**" (buffer-name (current-buffer))) | |
| 452 (not (= pt (point))))) | |
| 453 (setq pt (point)) | |
| 454 (if (looking-at "^\\[[0-9]* \\([^ ]+ \\)+<") | |
| 455 (mime-viewer/extract-content))))))) | |
| 456 (kill-buffer "*Preview-*Article**") | |
| 457 (setq gnus-show-mime sm) | |
| 458 )) | |
| 459 | |
| 460 ;;; Why??? | |
| 461 (make-variable-buffer-local 'gnus-extra-headers) | |
| 462 (make-variable-buffer-local 'nnmail-extra-headers) | |
| 463 | |
| 464 | |
| 465 (defun resend-to-schemadev () | |
| 466 (interactive) | |
| 467 (message "forwarding to xmlschema-dev") | |
| 468 (gnus-summary-resend-message "xmlschema-dev@w3.org" 1) | |
| 469 (gnus-summary-next-unread-article)) | |
| 470 | |
| 471 (defun brutal-resend () | |
| 472 (interactive) | |
| 473 (message "editing for resend. . .") | |
| 474 (unless (eq (gnus-summary-article-number) | |
| 475 gnus-current-article) | |
| 476 (gnus-summary-select-article t)) | |
| 477 (gnus-summary-toggle-header 1) | |
| 478 (with-current-buffer gnus-article-buffer | |
| 479 (toggle-read-only) | |
| 480 (gnus-article-date-original) | |
| 481 (goto-char (point-min)) | |
| 482 (replace-regexp "^\\(X-Diagnostic\\|X-Envelope-To\\|X-Original-To\\|Delivered-To\\):.*\n" "") | |
| 483 (goto-char (point-min)) | |
| 484 (gnus-summary-edit-article-done | |
| 485 (or (mail-header-references gnus-current-headers) "") | |
| 486 (gnus-group-read-only-p) gnus-summary-buffer nil)) | |
| 487 (call-interactively (function gnus-summary-resend-message)) | |
| 488 (gnus-summary-next-unread-article)) | |
| 489 | |
| 490 ; (unless (fboundp 'builtin-coding-system-p) | |
| 491 ; (fset 'builtin-coding-system-p (symbol-function 'coding-system-p)) | |
| 492 ; (defun coding-system-p (obj) | |
| 493 ; (cond | |
| 494 ; ((builtin-coding-system-p obj) t) | |
| 495 ; ((memq obj '(utf-8 gb2312 koi8-r iso-8859-1)) | |
| 496 ; (message (format "Coding system: %s" obj)) | |
| 497 ; t)))) | |
| 498 | |
| 499 ;;; dangerous hack to improve display of names and subjects in mail/news | |
| 500 (if nil (progn | |
| 501 (require 'mm-util) | |
| 502 (defun mm-decode-coding-string (str cs) | |
| 503 (if (and str (eq cs 'utf-8)) | |
| 504 (if (or (string-match "Â" str) | |
| 505 (string-match "Ã" str)) | |
| 506 (let* ((r 0) ; read pointer | |
| 507 (w 0) ; write pointer | |
| 508 (l (length str))) | |
| 509 (while (< r l) | |
| 510 (let* ((c (aref str r)) | |
| 511 (i (char-int c))) | |
| 512 (cond ((= i 194) | |
| 513 (aset str w (aref str (+ r 1))) | |
| 514 (setq r (+ r 2))) | |
| 515 ((= i 195) | |
| 516 (aset str w | |
| 517 (int-char | |
| 518 (+ 64 | |
| 519 (char-int (aref str (+ r 1)))))) | |
| 520 (setq r (+ r 2))) | |
| 521 (t | |
| 522 (aset str w c) | |
| 523 (setq r (+ r 1))))) | |
| 524 (setq w (+ w 1))) | |
| 525 (substring str 0 w)) | |
| 526 str) | |
| 527 str)) | |
| 528 | |
| 529 (defun mm-sort-coding-systems-predicate (a b) | |
| 530 ;; from mm-util, abort if no priorities | |
| 531 (or (not mm-coding-system-priorities) | |
| 532 (let ((priorities | |
| 533 (mapcar (lambda (cs) | |
| 534 ;; Note: invalid entries are dropped silently | |
| 535 (and (setq cs (mm-coding-system-p cs)) | |
| 536 (coding-system-base cs))) | |
| 537 mm-coding-system-priorities))) | |
| 538 (and (setq a (mm-coding-system-p a)) | |
| 539 (if (setq b (mm-coding-system-p b)) | |
| 540 (> (length (memq (coding-system-base a) priorities)) | |
| 541 (length (memq (coding-system-base b) priorities))) | |
| 542 t))))))) | |
| 543 | |
| 544 (require 'browse-url) | |
| 545 | |
| 546 ;;; This version collects extra lines if you use right-button | |
| 547 ;;; to click on a URL | |
| 548 (defun browse-url (url &rest args) | |
| 549 "Ask a WWW browser to load URL. | |
| 550 Prompts for a URL, defaulting to the URL at or before point. Variable | |
| 551 `browse-url-browser-function' says which browser to use." | |
| 552 (interactive (browse-url-interactive-arg "URL: ")) | |
| 553 (unless (interactive-p) | |
| 554 (setq args (or args (list browse-url-new-window-flag)))) | |
| 555 (if (and (boundp 'event)(= 3 (event-button event))) | |
| 556 (let ((thisLine url)) | |
| 557 (while (and (progn (forward-char (length thisLine)) | |
| 558 (eolp)) | |
| 559 (progn (forward-line 1) | |
| 560 (beginning-of-line) | |
| 561 (not (looking-at "\\s-")))) | |
| 562 (looking-at "\\S-*") | |
| 563 (setq thisLine (buffer-substring (match-beginning 0) | |
| 564 (match-end 0))) | |
| 565 (setq url (concat url thisLine))))) | |
| 566 (if (functionp browse-url-browser-function) | |
| 567 (apply browse-url-browser-function url args) | |
| 568 ;; The `function' can be an alist; look down it for first match | |
| 569 ;; and apply the function (which might be a lambda). | |
| 570 (catch 'done | |
| 571 (dolist (bf browse-url-browser-function) | |
| 572 (when (string-match (car bf) url) | |
| 573 (apply (cdr bf) url args) | |
| 574 (throw 'done t))) | |
| 575 (error "No browse-url-browser-function matching URL %s" | |
| 576 url)))) | |
| 577 | |
| 578 (defun gnus-user-format-function-H (dummy) | |
| 579 (format "%c" | |
| 580 (cond ((eq gnus-tmp-summary-live ?*) | |
| 581 ?*) | |
| 582 ((> (gnus-number-of-unseen-articles-in-group gnus-tmp-group) 0) | |
| 583 ?.) | |
| 584 (t ? )))) | |
| 585 | |
| 586 (defun ht-next-with-unseen (n) | |
| 587 (interactive "p") | |
| 588 (let* ((gvl (mapcar (function string-to-number) | |
| 589 (split-string gnus-version-number "\\."))) | |
| 590 (pattern (if (or (> (car gvl) 5) | |
| 591 (and (eq (car gvl) 5) | |
| 592 (or (> (cadr gvl) 10) | |
| 593 (and (eq (cadr gvl) 10) | |
| 594 (> (caddr gvl) 7))))) | |
| 595 "\\." | |
| 596 ":\\."))) | |
| 597 (if (looking-at pattern) | |
| 598 (if (< n 0) | |
| 599 (backward-char 1) | |
| 600 (forward-char 1))) | |
| 601 (let ((missing 0) | |
| 602 (winning (looking-at pattern))) | |
| 603 (while (and (zerop missing) | |
| 604 (not winning)) | |
| 605 (setq missing (gnus-group-next-unread-group n)) | |
| 606 (setq winning (looking-at pattern))) | |
| 607 winning))) | |
| 608 | |
| 609 (defun ht-read-group-unseen-only () | |
| 610 (interactive) | |
| 611 (gnus-group-read-group | |
| 612 (gnus-number-of-unseen-articles-in-group (gnus-group-group-name)))) | |
| 613 | |
| 614 (defun ht-previous-with-unseen (n) | |
| 615 (interactive "p") | |
| 616 (ht-next-with-unseen (- n))) | |
| 617 | |
| 618 (defun ht-gnus-note-save-to-group () | |
| 619 (let ((g (caar group-art))) | |
| 620 (if (not (member g ht-gnus-just-read)) | |
| 621 (setq ht-gnus-just-read (cons g ht-gnus-just-read))))) | |
| 622 | |
| 623 (defvar ht-stash-directory "/disk/scratch/mail/stash/") | |
| 624 | |
| 625 (defun ht-save-part (handle n) | |
| 626 (let ((sup-type (mm-handle-media-supertype handle)) | |
| 627 (sub-type (mm-handle-media-subtype handle))) | |
| 628 (message (format "%s %s/%s" n sup-type sub-type)) | |
| 629 (cond ((and (equal sup-type "multipart") | |
| 630 (or (equal sub-type "alternative") | |
| 631 (equal sub-type "related"))) | |
| 632 (let ((alts (cddr handle)) | |
| 633 (j 0)) | |
| 634 (while alts | |
| 635 (let* ((alt (pop alts)) | |
| 636 (handle-type (mm-handle-type alt))) | |
| 637 (let* ((sub (mm-handle-media-subtype alt)) | |
| 638 (ext (cdr | |
| 639 (assoc sub '(("calendar" . "vcs") | |
| 640 ("v-calendar" . "vcs")))))) | |
| 641 (setq j (+ j 1)) | |
| 642 (if (not (or (mail-content-type-get | |
| 643 (mm-handle-disposition alt) 'filename) | |
| 644 (mail-content-type-get | |
| 645 handle-type 'name))) | |
| 646 (nconc | |
| 647 handle-type | |
| 648 (list (cons 'name (format "%s.%s.%s" | |
| 649 n j (or ext sub)))))) | |
| 650 (ht-save-part alt (format "%s.%s" n j))))))) | |
| 651 ((and (equal sup-type "text")(not | |
| 652 (member sub-type '("html" | |
| 653 "v-calendar" | |
| 654 "calendar")))) | |
| 655 (message "Skipping text part: %s" (mm-handle-disposition handle))) | |
| 656 (t | |
| 657 (mm-save-part handle))))) | |
| 658 | |
| 659 (defun ht-move-to-pers (n) | |
| 660 (interactive "p") | |
| 661 (gnus-summary-move-article n | |
| 662 (concat | |
| 663 "nnml+ht:pers-" | |
| 664 (format-time-string "%Y-%m" (current-time))))) | |
| 665 | |
| 666 (defun ht-article-save-parts (n) | |
| 667 "Save non t/p MIME parts starting at N, which is the numerical prefix." | |
| 668 (interactive "p2") | |
| 669 (let ((window (get-buffer-window gnus-article-buffer 'visible)) | |
| 670 frame) | |
| 671 (when window | |
| 672 ;; It is necessary to select the article window so that | |
| 673 ;; `gnus-article-goto-part' may really move the point. | |
| 674 (setq frame (selected-frame)) | |
| 675 (gnus-select-frame-set-input-focus (window-frame window)) | |
| 676 (unwind-protect | |
| 677 (save-window-excursion | |
| 678 (select-window window) | |
| 679 (let ((len (length gnus-article-mime-handle-alist))) | |
| 680 (setq mm-default-directory ht-stash-directory) | |
| 681 (while (<= n len) | |
| 682 (gnus-article-goto-part n) | |
| 683 (let ((handle (cdr (assq n gnus-article-mime-handle-alist)))) | |
| 684 (ht-save-part handle n)) | |
| 685 (setq n (+ n 1)) | |
| 686 ))) | |
| 687 (gnus-select-frame-set-input-focus frame)))) | |
| 688 ) | |
| 689 | |
| 690 | |
| 691 (defun gnus-article-part-wrapper (n function) | |
| 692 (let ((window (get-buffer-window gnus-article-buffer 'visible)) | |
| 693 frame) | |
| 694 (when window | |
| 695 ;; It is necessary to select the article window so that | |
| 696 ;; `gnus-article-goto-part' may really move the point. | |
| 697 (setq frame (selected-frame)) | |
| 698 (gnus-select-frame-set-input-focus (window-frame window)) | |
| 699 (unwind-protect | |
| 700 (save-window-excursion | |
| 701 (select-window window) | |
| 702 (when (> n (length gnus-article-mime-handle-alist)) | |
| 703 (error "No such part")) | |
| 704 (gnus-article-goto-part n) | |
| 705 (let ((handle (cdr (assq n gnus-article-mime-handle-alist)))) | |
| 706 (funcall function handle))) | |
| 707 (gnus-select-frame-set-input-focus frame))))) | |
| 708 | |
| 709 (defun mhstore-me (dir) | |
| 710 (interactive (list (read-directory-name "Save parts to " "/tmp" "/tmp" t))) | |
| 711 (let ((art (gnus-summary-article-number))) | |
| 712 (let* ((grp-parts (split-string gnus-newsgroup-name ":")) | |
| 713 (meth (car grp-parts)) | |
| 714 (grp (cadr grp-parts))) | |
| 715 (if (string= meth "nnml+ht") | |
| 716 (let ((doit | |
| 717 (format "cd %s && mhstore -f /disk/scratch/mail/Mail/%s/%s -auto" | |
| 718 dir grp art))) | |
| 719 (message doit) | |
| 720 (shell-command doit)) | |
| 721 )))) | |
| 722 | |
| 723 (defun my-message-send-and-exit (&optional arg) | |
| 724 (interactive "P") | |
| 725 (let ((message-required-mail-headers | |
| 726 (if arg | |
| 727 (mapcar | |
| 728 (lambda(x) | |
| 729 (if(and(consp x)(eq(cdr x)'In-Reply-To)) | |
| 730 (cons 'optional 'xyzzy) | |
| 731 x)) | |
| 732 message-required-mail-headers) | |
| 733 message-required-mail-headers))) | |
| 734 (orig-message-send-and-exit))) | |
| 735 | |
| 736 (require 'message) | |
| 737 (if (not (fboundp 'orig-message-send-and-exit)) | |
| 738 (progn | |
| 739 (fset 'orig-message-send-and-exit (symbol-function 'message-send-and-exit)) | |
| 740 (fset 'message-send-and-exit (symbol-function 'my-message-send-and-exit)))) | |
| 741 | |
| 742 (provide 'my-news) |
