Remove nndb, nnkiboze and related code.

This commit is contained in:
Lars Magne Ingebrigtsen 2010-09-02 00:28:01 +00:00 committed by Katsumi Yamaoka
parent d743e0d118
commit f736244589
7 changed files with 11 additions and 830 deletions

View file

@ -721,7 +721,6 @@ Document Groups
Combined Groups
* Virtual Groups:: Combining articles from many groups.
* Kibozed Groups:: Looking through parts of the newsfeed for articles.
Email Based Diary
@ -2624,15 +2623,6 @@ default a group pointing to the most recent articles will be created
(@code{gnus-group-recent-archive-directory}), but given a prefix, a full
group will be created from @code{gnus-group-archive-directory}.
@item G k
@kindex G k (Group)
@findex gnus-group-make-kiboze-group
@cindex nnkiboze
Make a kiboze group. You will be prompted for a name, for a regexp to
match groups to be ``included'' in the kiboze group, and a series of
strings to match on headers (@code{gnus-group-make-kiboze-group}).
@xref{Kibozed Groups}.
@item G D
@kindex G D (Group)
@findex gnus-group-enter-directory
@ -4420,8 +4410,7 @@ which point to the ``real'' message files (if mbox is used, copies are
made). Since mairix already presents search results in such a virtual
mail folder, it is very well suited for using it as an external program
for creating @emph{smart} mail folders, which represent certain mail
searches. This is similar to a Kiboze group (@pxref{Kibozed Groups}),
but much faster.
searches.
@node nnmairix requirements
@subsubsection nnmairix requirements
@ -18933,7 +18922,6 @@ groups.
@menu
* Virtual Groups:: Combining articles from many groups.
* Kibozed Groups:: Looking through parts of the newsfeed for articles.
@end menu
@ -19023,58 +19011,6 @@ from component groups---group parameters, for instance, are not
inherited.
@node Kibozed Groups
@subsection Kibozed Groups
@cindex nnkiboze
@cindex kibozing
@dfn{Kibozing} is defined by the @acronym{OED} as ``grepping through
(parts of) the news feed''. @code{nnkiboze} is a back end that will
do this for you. Oh joy! Now you can grind any @acronym{NNTP} server
down to a halt with useless requests! Oh happiness!
@kindex G k (Group)
To create a kibozed group, use the @kbd{G k} command in the group
buffer.
The address field of the @code{nnkiboze} method is, as with
@code{nnvirtual}, a regexp to match groups to be ``included'' in the
@code{nnkiboze} group. That's where most similarities between
@code{nnkiboze} and @code{nnvirtual} end.
In addition to this regexp detailing component groups, an
@code{nnkiboze} group must have a score file to say what articles are
to be included in the group (@pxref{Scoring}).
@kindex M-x nnkiboze-generate-groups
@findex nnkiboze-generate-groups
You must run @kbd{M-x nnkiboze-generate-groups} after creating the
@code{nnkiboze} groups you want to have. This command will take time.
Lots of time. Oodles and oodles of time. Gnus has to fetch the
headers from all the articles in all the component groups and run them
through the scoring process to determine if there are any articles in
the groups that are to be part of the @code{nnkiboze} groups.
Please limit the number of component groups by using restrictive
regexps. Otherwise your sysadmin may become annoyed with you, and the
@acronym{NNTP} site may throw you off and never let you back in again.
Stranger things have happened.
@code{nnkiboze} component groups do not have to be alive---they can be dead,
and they can be foreign. No restrictions.
@vindex nnkiboze-directory
The generation of an @code{nnkiboze} group means writing two files in
@code{nnkiboze-directory}, which is @file{~/News/kiboze/} by default.
One contains the @acronym{NOV} header lines for all the articles in
the group, and the other is an additional @file{.newsrc} file to store
information on what groups have been searched through to find
component articles.
Articles marked as read in the @code{nnkiboze} group will have
their @acronym{NOV} lines removed from the @acronym{NOV} file.
@node Email Based Diary
@section Email Based Diary
@cindex diary
@ -27422,10 +27358,6 @@ cluttering up the @file{.emacs} file.
You can set the process mark on both groups and articles and perform
operations on all the marked items (@pxref{Process/Prefix}).
@item
You can grep through a subset of groups and create a group from the
results (@pxref{Kibozed Groups}).
@item
You can list subsets of groups according to, well, anything
(@pxref{Listing Groups}).
@ -29134,8 +29066,8 @@ As the variables for the other back ends, there are
@code{nnfolder-nov-is-evil}, @code{nnimap-nov-is-evil},
@code{nnml-nov-is-evil}, and @code{nnspool-nov-is-evil}. Note that a
non-@code{nil} value for @code{gnus-nov-is-evil} overrides all those
variables.@footnote{Although the back ends @code{nnkiboze}, and
@code{nnwfm} don't have their own nn*-nov-is-evil.}
variables.@footnote{Although the back end @code{nnwfm} doesn't have
its own nn*-nov-is-evil.}
@end table

View file

@ -5,6 +5,10 @@
2010-09-01 Lars Magne Ingebrigtsen <larsi@gnus.org>
* nnkiboze.el: Removed.
* nndb.el: Removed.
* gnus-html.el (gnus-html-put-image): Use the deleted text as the image
alt text.
(gnus-html-rescale-image): Try to get the rescaling logic right for

View file

@ -660,7 +660,6 @@ simple manner.")
"h" gnus-group-make-help-group
"u" gnus-group-make-useful-group
"a" gnus-group-make-archive-group
"k" gnus-group-make-kiboze-group
"l" gnus-group-nnimap-edit-acl
"m" gnus-group-make-group
"E" gnus-group-edit-group
@ -931,7 +930,6 @@ simple manner.")
["Add the archive group" gnus-group-make-archive-group t]
["Make a doc group..." gnus-group-make-doc-group t]
["Make a web group..." gnus-group-make-web-group t]
["Make a kiboze group..." gnus-group-make-kiboze-group t]
["Make a virtual group..." gnus-group-make-empty-virtual t]
["Add a group to a virtual..." gnus-group-add-to-virtual t]
["Make an ephemeral group..." gnus-group-read-ephemeral-group t]
@ -982,7 +980,6 @@ simple manner.")
["Browse foreign server..." gnus-group-browse-foreign-server t]
["Enter server buffer" gnus-group-enter-server-mode t]
["Expire all expirable articles" gnus-group-expire-all-groups t]
["Generate any kiboze groups" nnkiboze-generate-groups t]
["Gnus version" gnus-version t]
["Save .newsrc files" gnus-group-save-newsrc t]
["Suspend Gnus" gnus-group-suspend t]
@ -3116,41 +3113,6 @@ mail messages or news articles in files that have numeric names."
(gnus-group-real-name group)
(list 'nndir (gnus-group-real-name group) (list 'nndir-directory dir)))))
(defvar nnkiboze-score-file)
(declare-function nnkiboze-score-file "nnkiboze" (group))
(defun gnus-group-make-kiboze-group (group address scores)
"Create an nnkiboze group.
The user will be prompted for a name, a regexp to match groups, and
score file entries for articles to include in the group."
(interactive
(list
(read-string "nnkiboze group name: ")
(read-string "Source groups (regexp): ")
(let ((headers (mapcar 'list
'("subject" "from" "number" "date" "message-id"
"references" "chars" "lines" "xref"
"followup" "all" "body" "head")))
scores header regexp regexps)
(while (not (equal "" (setq header (completing-read
"Match on header: " headers nil t))))
(setq regexps nil)
(while (not (equal "" (setq regexp (read-string
(format "Match on %s (regexp): "
header)))))
(push (list regexp nil nil 'r) regexps))
(push (cons header regexps) scores))
scores)))
(gnus-group-make-group group "nnkiboze" address)
(let* ((nnkiboze-current-group group)
(score-file (car (nnkiboze-score-file "")))
(score-dir (file-name-directory score-file)))
(unless (file-exists-p score-dir)
(make-directory score-dir))
(with-temp-file score-file
(let (emacs-lisp-mode-hook)
(gnus-pp scores)))))
(defun gnus-group-add-to-virtual (n vgroup)
"Add the current group to a virtual group."
(interactive

View file

@ -1740,7 +1740,6 @@ slower."
("nneething" none address prompt-address physical-address)
("nndoc" none address prompt-address)
("nnbabyl" mail address respool)
("nnkiboze" post virtual)
("nndraft" post-mail)
("nnfolder" mail respool address)
("nngateway" post-mail address prompt-address physical-address)

View file

@ -1,325 +0,0 @@
;;; nndb.el --- nndb access for Gnus
;; Copyright (C) 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006, 2007,
;; 2008, 2009, 2010 Free Software Foundation, Inc.
;; Author: Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>
;; Kai Grossjohann <grossjohann@ls6.informatik.uni-dortmund.de>
;; Joe Hildebrand <joe.hildebrand@ilg.com>
;; David Blacka <davidb@rwhois.net>
;; Keywords: news
;; This file is part of GNU Emacs.
;; GNU Emacs 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 3 of the License, or
;; (at your option) any later version.
;; GNU Emacs 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. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;;; This was based upon Kai Grossjohan's shamessly snarfed code and
;;; further modified by Joe Hildebrand. It has been updated for Red
;;; Gnus.
;; TODO:
;;
;; * Fix bug where server connection can be lost and impossible to regain
;; This hasn't happened to me in a while; think it was fixed in Rgnus
;;
;; * make it handle different nndb servers seemlessly
;;
;; * Optimize expire if FORCE
;;
;; * Optimize move (only expire once)
;;
;; * Deal with add/deletion of groups
;;
;; * make the backend TOUCH an article when marked as expireable (will
;; make article expire 'expiry' days after that moment).
;;; Code:
;; For Emacs < 22.2.
(eval-and-compile
(unless (fboundp 'declare-function) (defmacro declare-function (&rest r))))
;;-
;; Register nndb with known select methods.
(require 'gnus-start)
(unless (assoc "nndb" gnus-valid-select-methods)
(gnus-declare-backend "nndb" 'mail 'respool 'address 'prompt-address))
(require 'nnmail)
(require 'nnheader)
(require 'nntp)
(eval-when-compile (require 'cl))
;; Declare nndb as derived from nntp
(nnoo-declare nndb nntp)
;; Variables specific to nndb
;;- currently not used but just in case...
(defvoo nndb-deliver-program "nndel"
"*The program used to put a message in an NNDB group.")
(defvoo nndb-server-side-expiry nil
"If t, expiry calculation will occur on the server side.")
(defvoo nndb-set-expire-date-on-mark nil
"If t, the expiry date for a given article will be set to the time
it was marked as expireable; otherwise the date will be the time the
article was posted to nndb")
;; Variables copied from nntp
(defvoo nndb-server-opened-hook '(nntp-send-authinfo-from-file)
"Like nntp-server-opened-hook."
nntp-server-opened-hook)
(defvoo nndb-address "localhost"
"*The name of the NNDB server."
nntp-address)
(defvoo nndb-port-number 9000
"*Port number to connect to."
nntp-port-number)
;; change to 'news if you are actually using nndb for news
(defvoo nndb-article-type 'mail)
(defvoo nndb-status-string nil "" nntp-status-string)
(defconst nndb-version "nndb 0.7"
"Version numbers of this version of NNDB.")
;;; Interface functions.
(nnoo-define-basics nndb)
;;------------------------------------------------------------------
;; this function turns the lisp list into a string list. There is
;; probably a more efficient way to do this.
(defun nndb-build-article-string (articles)
(let (art-string art)
(while articles
(setq art (pop articles))
(setq art-string (concat art-string art " ")))
art-string))
(defun nndb-build-expire-rest-list (total expire)
(let (art rest)
(while total
(setq art (pop total))
(if (memq art expire)
()
(push art rest)))
rest))
;;
(deffoo nndb-request-type (group &optional article)
nndb-article-type)
;; nndb-request-update-info does not exist and is not needed
;; nndb-request-update-mark does not exist; it should be used to TOUCH
;; articles as they are marked exipirable
(defun nndb-touch-article (group article)
(nntp-send-command nil "X-TOUCH" article))
(deffoo nndb-request-update-mark
(group article mark)
"Sets the expiry date for ARTICLE in GROUP to now, if the mark is 'E'"
(if (and nndb-set-expire-date-on-mark (string-equal mark "E"))
(nndb-touch-article group article))
mark)
;; nndb-request-create-group -- currently this isn't necessary; nndb
;; creates groups on demand.
;; todo -- use some other time than the creation time of the article
;; best is time since article has been marked as expirable
(defun nndb-request-expire-articles-local
(articles &optional group server force)
"Let gnus do the date check and issue the delete commands."
(let (msg art delete-list (num-delete 0) rest)
(nntp-possibly-change-group group server)
(while articles
(setq art (pop articles))
(nntp-send-command "^\\([23]\\|^423\\).*\n" "X-DATE" art)
(setq msg (nndb-status-message))
(if (string-match "^423" msg)
()
(or (string-match "'\\(.+\\)'" msg)
(error "Not a valid response for X-DATE command: %s"
msg))
(if (nnmail-expired-article-p
group
(date-to-time (substring msg (match-beginning 1) (match-end 1)))
force)
(progn
(setq delete-list (concat delete-list " " (int-to-string art)))
(setq num-delete (1+ num-delete)))
(push art rest))))
(if (> (length delete-list) 0)
(progn
(nnheader-message 5 "Deleting %s article(s) from %s"
(int-to-string num-delete) group)
(nntp-send-command "^[23].*\n" "X-DELETE" delete-list))
)
(nnheader-message 5 "")
(nconc rest articles)))
(defun nndb-get-remote-expire-response ()
(let (list)
(set-buffer nntp-server-buffer)
(goto-char (point-min))
(if (looking-at "^[34]")
;; x-expire returned error--presume no articles were expirable)
(setq list nil)
;; otherwise, pull all of the following numbers into the list
(re-search-forward "follows\r?\n?" nil t)
(while (re-search-forward "^[0-9]+$" nil t)
(push (string-to-number (match-string 0)) list)))
list))
(defun nndb-request-expire-articles-remote
(articles &optional group server force)
"Let the nndb backend expire articles"
(let (days art-string delete-list (num-delete 0))
(nntp-possibly-change-group group server)
;; first calculate the wait period in days
(setq days (or (and nnmail-expiry-wait-function
(funcall nnmail-expiry-wait-function group))
nnmail-expiry-wait))
;; now handle the special cases
(cond (force
(setq days 0))
((eq days 'never)
;; This isn't an expirable group.
(setq days -1))
((eq days 'immediate)
(setq days 0)))
;; build article string
(setq art-string (concat days " " (nndb-build-article-string articles)))
(nntp-send-command "^\.\r?\n\\|^[345].*\n" "X-EXPIRE" art-string)
(setq delete-list (nndb-get-remote-expire-response))
(setq num-delete (length delete-list))
(if (> num-delete 0)
(nnheader-message 5 "Deleting %s article(s) from %s"
(int-to-string num-delete) group))
(nndb-build-expire-rest-list articles delete-list)))
(deffoo nndb-request-expire-articles
(articles &optional group server force)
"Expires ARTICLES from GROUP on SERVER.
If FORCE, delete regardless of exiration date, otherwise use normal
expiry mechanism."
(if nndb-server-side-expiry
(nndb-request-expire-articles-remote articles group server force)
(nndb-request-expire-articles-local articles group server force)))
;; _Something_ defines it...
(declare-function nndb-request-article "nndb" t t)
(deffoo nndb-request-move-article
(article group server accept-form &optional last move-is-internal)
"Move ARTICLE (a number) from GROUP on SERVER.
Evals ACCEPT-FORM in current buffer, where the article is.
Optional LAST is ignored."
;; we guess that the second arg in accept-form is the new group,
;; which it will be for nndb, which is all that matters anyway
(let ((new-group (nth 1 accept-form)) result)
(nntp-possibly-change-group group server)
;; use the move command for nndb-to-nndb moves
(if (string-match "^nndb" new-group)
(let ((new-group-name (gnus-group-real-name new-group)))
(nntp-send-command "^[23].*\n" "X-MOVE" article new-group-name)
(cons new-group article))
;; else move normally
(let ((artbuf (get-buffer-create " *nndb move*")))
(and
(nndb-request-article article group server artbuf)
(save-excursion
(set-buffer artbuf)
(insert-buffer-substring nntp-server-buffer)
(setq result (eval accept-form))
(kill-buffer (current-buffer))
result)
(nndb-request-expire-articles (list article)
group
server
t))
result)
)))
(deffoo nndb-request-accept-article (group server &optional last)
"The article in the current buffer is put into GROUP."
(nntp-possibly-change-group group server)
(let (art msg)
(when (nntp-send-command "^[23].*\r?\n" "ACCEPT" group)
(nnheader-insert "")
(nntp-send-buffer "^[23].*\n"))
(set-buffer nntp-server-buffer)
(setq msg (buffer-string))
(or (string-match "^\\([0-9]+\\)" msg)
(error "nndb: %s" msg))
(setq art (substring msg (match-beginning 1) (match-end 1)))
(nnheader-message 5 "nndb: accepted %s" art)
(list art)))
(deffoo nndb-request-replace-article (article group buffer)
"ARTICLE is the number of the article in GROUP to be replaced with the contents of the BUFFER."
(set-buffer buffer)
(when (nntp-send-command "^[23].*\r?\n" "X-REPLACE" (int-to-string article))
(nnheader-insert "")
(nntp-send-buffer "^[23.*\n")
(list (int-to-string article))))
; nndb-request-delete-group does not exist
; todo -- maybe later
; nndb-request-rename-group does not exist
; todo -- maybe later
;; -- standard compatibility functions
(deffoo nndb-status-message (&optional server)
"Return server status as a string."
(set-buffer nntp-server-buffer)
(buffer-string))
;; Import stuff from nntp
(nnoo-import nndb
(nntp))
(provide 'nndb)
;; arch-tag: 83bd6fb4-58d9-4fed-a901-c6c625ad5f8a
;;; nndb.el ends here

View file

@ -263,10 +263,10 @@
;; I have tried to make the code expandable. Basically, it is divided
;; into two layers. The upper layer is somewhat like the `nnvirtual'
;; or `nnkiboze' backends: given a specification of what articles to
;; show from another backend, it creates a group containing exactly
;; those articles. The lower layer issues a query to a search engine
;; and produces such a specification of what articles to show from the
;; backend: given a specification of what articles to show from
;; another backend, it creates a group containing exactly those
;; articles. The lower layer issues a query to a search engine and
;; produces such a specification of what articles to show from the
;; other backend.
;; The interface between the two layers consists of the single

View file

@ -1,391 +0,0 @@
;;; nnkiboze.el --- select virtual news access for Gnus
;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
;; 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
;; Keywords: news
;; This file is part of GNU Emacs.
;; GNU Emacs 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 3 of the License, or
;; (at your option) any later version.
;; GNU Emacs 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. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; The other access methods (nntp, nnspool, etc) are general news
;; access methods. This module relies on Gnus and can't be used
;; separately.
;;; Code:
(require 'nntp)
(require 'nnheader)
(require 'gnus)
(require 'gnus-score)
(require 'nnoo)
(require 'mm-util)
(eval-when-compile (require 'cl))
(nnoo-declare nnkiboze)
(defvoo nnkiboze-directory (nnheader-concat gnus-directory "kiboze/")
"nnkiboze will put its files in this directory.")
(defvoo nnkiboze-level 9
"The maximum level to be searched for articles.")
(defvoo nnkiboze-remove-read-articles t
"If non-nil, nnkiboze will remove read articles from the kiboze group.")
(defvoo nnkiboze-ephemeral nil
"If non-nil, don't store any data anywhere.")
(defvoo nnkiboze-scores nil
"Score rules for generating the nnkiboze group.")
(defvoo nnkiboze-regexp nil
"Regexp for matching component groups.")
(defvoo nnkiboze-file-coding-system mm-text-coding-system
"Coding system for nnkiboze files.")
(defconst nnkiboze-version "nnkiboze 1.0")
(defvoo nnkiboze-current-group nil)
(defvoo nnkiboze-status-string "")
(defvoo nnkiboze-headers nil)
;;; Interface functions.
(nnoo-define-basics nnkiboze)
(deffoo nnkiboze-retrieve-headers (articles &optional group server fetch-old)
(nnkiboze-possibly-change-group group)
(unless gnus-nov-is-evil
(if (stringp (car articles))
'headers
(let ((nov (nnkiboze-nov-file-name)))
(when (file-exists-p nov)
(save-excursion
(set-buffer nntp-server-buffer)
(erase-buffer)
(let ((nnheader-file-coding-system nnkiboze-file-coding-system))
(nnheader-insert-file-contents nov))
(nnheader-nov-delete-outside-range
(car articles) (car (last articles)))
'nov))))))
(deffoo nnkiboze-request-article (article &optional newsgroup server buffer)
(nnkiboze-possibly-change-group newsgroup)
(if (not (numberp article))
;; This is a real kludge. It might not work at times, but it
;; does no harm I think. The only alternative is to offer no
;; article fetching by message-id at all.
(nntp-request-article article newsgroup gnus-nntp-server buffer)
(let* ((header (gnus-summary-article-header article))
(xref (mail-header-xref header))
num group)
(unless xref
(error "nnkiboze: No xref"))
(unless (string-match " \\([^ ]+\\):\\([0-9]+\\)" xref)
(error "nnkiboze: Malformed xref"))
(setq num (string-to-number (match-string 2 xref))
group (match-string 1 xref))
(or (with-current-buffer buffer
(or (and gnus-use-cache (gnus-cache-request-article num group))
(gnus-agent-request-article num group)))
(gnus-request-article num group buffer)))))
(deffoo nnkiboze-request-scan (&optional group server)
(nnkiboze-possibly-change-group group)
(nnkiboze-generate-group (concat "nnkiboze:" group)))
(deffoo nnkiboze-request-group (group &optional server dont-check)
"Make GROUP the current newsgroup."
(nnkiboze-possibly-change-group group)
(if dont-check
t
(let ((nov-file (nnkiboze-nov-file-name))
beg end total)
(save-excursion
(set-buffer nntp-server-buffer)
(erase-buffer)
(unless (file-exists-p nov-file)
(nnkiboze-request-scan group))
(if (not (file-exists-p nov-file))
(nnheader-report 'nnkiboze "Can't select group %s" group)
(let ((nnheader-file-coding-system nnkiboze-file-coding-system))
(nnheader-insert-file-contents nov-file))
(if (zerop (buffer-size))
(nnheader-insert "211 0 0 0 %s\n" group)
(goto-char (point-min))
(when (looking-at "[0-9]+")
(setq beg (read (current-buffer))))
(goto-char (point-max))
(when (re-search-backward "^[0-9]" nil t)
(setq end (read (current-buffer))))
(setq total (count-lines (point-min) (point-max)))
(nnheader-insert "211 %d %d %d %s\n" total beg end group)))))))
(deffoo nnkiboze-close-group (group &optional server)
(nnkiboze-possibly-change-group group)
;; Remove NOV lines of articles that are marked as read.
(when (and (file-exists-p (nnkiboze-nov-file-name))
nnkiboze-remove-read-articles)
(let ((coding-system-for-write nnkiboze-file-coding-system))
(with-temp-file (nnkiboze-nov-file-name)
(let ((cur (current-buffer))
(nnheader-file-coding-system nnkiboze-file-coding-system))
(nnheader-insert-file-contents (nnkiboze-nov-file-name))
(goto-char (point-min))
(while (not (eobp))
(if (not (gnus-article-read-p (read cur)))
(forward-line 1)
(gnus-delete-line))))))
(setq nnkiboze-current-group nil)))
(deffoo nnkiboze-open-server (server &optional defs)
(unless (assq 'nnkiboze-regexp defs)
(push `(nnkiboze-regexp ,server)
defs))
(nnoo-change-server 'nnkiboze server defs))
(deffoo nnkiboze-request-delete-group (group &optional force server)
(nnkiboze-possibly-change-group group)
(when force
(let ((files (nconc
(nnkiboze-score-file group)
(list (nnkiboze-nov-file-name)
(nnkiboze-nov-file-name ".newsrc")))))
(while files
(and (file-exists-p (car files))
(file-writable-p (car files))
(delete-file (car files)))
(setq files (cdr files)))))
(setq nnkiboze-current-group nil)
t)
(nnoo-define-skeleton nnkiboze)
;;; Internal functions.
(defun nnkiboze-possibly-change-group (group)
(setq nnkiboze-current-group group))
(defun nnkiboze-prefixed-name (group)
(gnus-group-prefixed-name group '(nnkiboze "")))
;;;###autoload
(defun nnkiboze-generate-groups ()
"\"Usage: emacs -batch -l nnkiboze -f nnkiboze-generate-groups\".
Finds out what articles are to be part of the nnkiboze groups."
(interactive)
(let ((mail-sources nil)
(gnus-use-dribble-file nil)
(gnus-read-active-file t)
(gnus-expert-user t))
(gnus))
(let* ((gnus-newsrc-alist (gnus-copy-sequence gnus-newsrc-alist))
(newsrc (cdr gnus-newsrc-alist))
gnus-newsrc-hashtb info)
(gnus-make-hashtable-from-newsrc-alist)
;; We have copied all the newsrc alist info over to local copies
;; so that we can mess all we want with these lists.
(while (setq info (pop newsrc))
(when (string-match "nnkiboze" (gnus-info-group info))
;; For each kiboze group, we call this function to generate
;; it.
(nnkiboze-generate-group (gnus-info-group info) t))))
(save-excursion
(set-buffer gnus-group-buffer)
(gnus-group-list-groups)))
(defun nnkiboze-score-file (group)
(list (expand-file-name
(concat (file-name-as-directory gnus-kill-files-directory)
(nnheader-translate-file-chars
(concat (nnkiboze-prefixed-name nnkiboze-current-group)
"." gnus-score-file-suffix))))))
(defun nnkiboze-generate-group (group &optional inhibit-list-groups)
(let* ((info (gnus-get-info group))
(newsrc-file (concat nnkiboze-directory
(nnheader-translate-file-chars
(concat group ".newsrc"))))
(nov-file (concat nnkiboze-directory
(nnheader-translate-file-chars
(concat group ".nov"))))
method nnkiboze-newsrc gname newsrc active
ginfo lowest glevel orig-info nov-buffer
;; Bind various things to nil to make group entry faster.
(gnus-expert-user t)
(gnus-large-newsgroup nil)
(gnus-score-find-score-files-function 'nnkiboze-score-file)
;; Use only nnkiboze-score-file!
(gnus-score-use-all-scores nil)
(gnus-use-scoring t)
(gnus-verbose (min gnus-verbose 3))
gnus-select-group-hook gnus-summary-prepare-hook
gnus-thread-sort-functions gnus-show-threads
gnus-visual gnus-suppress-duplicates num-unread)
(unless info
(error "No such group: %s" group))
;; Load the kiboze newsrc file for this group.
(when (file-exists-p newsrc-file)
(load newsrc-file))
(let ((coding-system-for-write nnkiboze-file-coding-system))
(gnus-make-directory (file-name-directory nov-file))
(with-temp-file nov-file
(mm-disable-multibyte)
(when (file-exists-p nov-file)
(insert-file-contents nov-file))
(setq nov-buffer (current-buffer))
;; Go through the active hashtb and add new all groups that match the
;; kiboze regexp.
(mapatoms
(lambda (group)
(and (string-match nnkiboze-regexp
(setq gname (symbol-name group))) ; Match
(not (assoc gname nnkiboze-newsrc)) ; It isn't registered
(numberp (car (symbol-value group))) ; It is active
(or (> nnkiboze-level 7)
(and (setq glevel
(gnus-info-level (gnus-get-info gname)))
(>= nnkiboze-level glevel)))
(not (string-match "^nnkiboze:" gname)) ; Exclude kibozes
(push (cons gname (1- (car (symbol-value group))))
nnkiboze-newsrc)))
gnus-active-hashtb)
;; `newsrc' is set to the list of groups that possibly are
;; component groups to this kiboze group. This list has elements
;; on the form `(GROUP . NUMBER)', where NUMBER is the highest
;; number that has been kibozed in GROUP in this kiboze group.
(setq newsrc nnkiboze-newsrc)
(while newsrc
(if (not (setq active (gnus-active (caar newsrc))))
;; This group isn't active after all, so we remove it from
;; the list of component groups.
(setq nnkiboze-newsrc (delq (car newsrc) nnkiboze-newsrc))
(setq lowest (cdar newsrc))
;; Ok, we have a valid component group, so we jump to it.
(switch-to-buffer gnus-group-buffer)
(gnus-group-jump-to-group (caar newsrc))
(gnus-message 3 "nnkiboze: Checking %s..." (caar newsrc))
(setq ginfo (gnus-get-info (gnus-group-group-name))
orig-info (gnus-copy-sequence ginfo)
num-unread (gnus-group-unread (caar newsrc)))
(unwind-protect
(progn
;; We set all list of article marks to nil. Since we operate
;; on copies of the real lists, we can destroy anything we
;; want here.
(when (nth 3 ginfo)
(setcar (nthcdr 3 ginfo) nil))
;; We set the list of read articles to be what we expect for
;; this kiboze group -- either nil or `(1 . LOWEST)'.
(when ginfo
(setcar (nthcdr 2 ginfo)
(and (not (= lowest 1)) (cons 1 lowest))))
(when (and (or (not ginfo)
(> (length (gnus-list-of-unread-articles
(car ginfo)))
0))
(progn
(ignore-errors
(gnus-group-select-group nil))
(eq major-mode 'gnus-summary-mode)))
;; We are now in the group where we want to be.
(setq method (gnus-find-method-for-group
gnus-newsgroup-name))
(when (eq method gnus-select-method)
(setq method nil))
;; We go through the list of scored articles.
(while gnus-newsgroup-scored
(when (> (caar gnus-newsgroup-scored) lowest)
;; If it has a good score, then we enter this article
;; into the kiboze group.
(nnkiboze-enter-nov
nov-buffer
(gnus-summary-article-header
(caar gnus-newsgroup-scored))
gnus-newsgroup-name))
(setq gnus-newsgroup-scored (cdr gnus-newsgroup-scored)))
;; That's it. We exit this group.
(when (eq major-mode 'gnus-summary-mode)
(kill-buffer (current-buffer)))))
;; Restore the proper info.
(when ginfo
(setcdr ginfo (cdr orig-info)))
(setcar (gnus-group-entry (caar newsrc)) num-unread)))
(setcdr (car newsrc) (cdr active))
(gnus-message 3 "nnkiboze: Checking %s...done" (caar newsrc))
(setq newsrc (cdr newsrc)))))
;; We save the kiboze newsrc for this group.
(gnus-make-directory (file-name-directory newsrc-file))
(with-temp-file newsrc-file
(mm-disable-multibyte)
(insert "(setq nnkiboze-newsrc '")
(gnus-prin1 nnkiboze-newsrc)
(insert ")\n"))
(unless inhibit-list-groups
(save-excursion
(set-buffer gnus-group-buffer)
(gnus-group-list-groups)))
t))
(defun nnkiboze-enter-nov (buffer header group)
(save-excursion
(set-buffer buffer)
(goto-char (point-max))
(let ((prefix (gnus-group-real-prefix group))
(oheader (copy-sequence header))
article)
(if (zerop (forward-line -1))
(progn
(setq article (1+ (read (current-buffer))))
(forward-line 1))
(setq article 1))
(mail-header-set-number oheader article)
(with-temp-buffer
(insert (or (mail-header-xref oheader) ""))
(goto-char (point-min))
(if (re-search-forward " [^ ]+:[0-9]+" nil t)
(goto-char (match-beginning 0))
(or (eobp) (forward-char 1)))
;; The first Xref has to be the group this article
;; really came for - this is the article nnkiboze
;; will request when it is asked for the article.
(insert " " group ":"
(int-to-string (mail-header-number header)) " ")
(while (re-search-forward " [^ ]+:[0-9]+" nil t)
(goto-char (1+ (match-beginning 0)))
(insert prefix))
(mail-header-set-xref oheader (buffer-string)))
(nnheader-insert-nov oheader))))
(defun nnkiboze-nov-file-name (&optional suffix)
(concat (file-name-as-directory nnkiboze-directory)
(nnheader-translate-file-chars
(concat (nnkiboze-prefixed-name nnkiboze-current-group)
(or suffix ".nov")))))
(provide 'nnkiboze)
;; arch-tag: 66068271-bdc9-4801-bcde-779702e73a05
;;; nnkiboze.el ends here