;; -*- emacs-lisp -*-
;;; gnus-track-authors.el --- record where authors have been seen before

;; Author: Mark Triggs <mst@dishevelled.net>

;; This file is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.

;; This file is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING.  If not, write to
;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.

;;; Commentary:

;; Stalking made easy! I'm not sure what inspired me to write this. It
;; basically snarfs your group headers and records the details of posters. When
;; you see a familiar name, 'M-x gnus-where-from' tells you what groups you've
;; seen them on before.
;;
;; Will I use this? Not sure.

;;; Code:

(defvar author-db (make-hash-table :test 'equal)
  "A hash table of all authors seen while reading groups")
(defvar author-db-file "~/.gnus-author-db.el")

(defun gnus-summary-grok-group ()
  (interactive)
  (let ((group (subseq gnus-newsgroup-name
                       (1+ (or (position ?: gnus-newsgroup-name)
                               -1)))))
    (dolist (author (mapcar #'gnus-header-from gnus-newsgroup-headers))
      (pushnew group (gethash author author-db) :test 'equal))))

(defun gnus-where-from ()
  "What groups has the current author been seen in?"
  (interactive)
  (message "%s"
           (gethash (gnus-header-from
                     (gnus-summary-article-header
                      (gnus-summary-article-number)))
                    author-db)))

(defun gnus-save-author-db ()
  "Write the author database to disk"
  (interactive)
  (with-temp-buffer
    (font-lock-mode -1)
    (insert (format "%S" `(setq author-db ,(dump-hash author-db))))
    (let ((buffer-file-coding-system 'compound-text-with-extensions))
      (write-file author-db-file nil))))

(defun gnus-load-author-db ()
  (interactive)
  (load author-db-file))

(defun dump-hash (hash)
  `(let ((newhash (make-hash-table :test ',(hash-table-test hash))))
     ,@(let ((acc '()))
         (maphash (lambda (k v) (push `(puthash ,k ',v newhash) acc))
                  hash)
         acc)
     newhash))

(add-hook 'gnus-summary-prepared-hook 'gnus-summary-grok-group)
(add-hook 'gnus-exit-gnus-hook 'gnus-save-author-db)

(define-key gnus-summary-mode-map (kbd "C-c ?") 'gnus-where-from)

(gnus-load-author-db)

(provide 'gnus-track-authors)
;;; gnus-track-authors.el ends here
