*** empty log message ***
[bpt/emacs.git] / lisp / gnus / nnultimate.el
CommitLineData
185a608e 1;;; nnultimate.el --- interfacing with the Ultimate Bulletin Board system -*- coding: iso-latin-1 -*-
c113de23
GM
2;; Copyright (C) 1999, 2000 Free Software Foundation, Inc.
3
4;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
5;; Keywords: news
6
7;; This file is part of GNU Emacs.
8
9;; GNU Emacs is free software; you can redistribute it and/or modify
10;; it under the terms of the GNU General Public License as published by
11;; the Free Software Foundation; either version 2, or (at your option)
12;; any later version.
13
14;; GNU Emacs is distributed in the hope that it will be useful,
15;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;; GNU General Public License for more details.
18
19;; You should have received a copy of the GNU General Public License
20;; along with GNU Emacs; see the file COPYING. If not, write to the
21;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22;; Boston, MA 02111-1307, USA.
23
24;;; Commentary:
25
26;; Note: You need to have `url' and `w3' installed for this
27;; backend to work.
28
29;;; Code:
30
31(eval-when-compile (require 'cl))
32
33(require 'nnoo)
34(require 'message)
35(require 'gnus-util)
36(require 'gnus)
37(require 'nnmail)
38(require 'mm-util)
39(eval-when-compile
40 (ignore-errors
41 (require 'nnweb)))
42;; Report failure to find w3 at load time if appropriate.
43(eval '(require 'nnweb))
44
45(nnoo-declare nnultimate)
46
47(defvoo nnultimate-directory (nnheader-concat gnus-directory "ultimate/")
48 "Where nnultimate will save its files.")
49
50(defvoo nnultimate-address ""
51 "The address of the Ultimate bulletin board.")
52
53;;; Internal variables
54
55(defvar nnultimate-groups-alist nil)
56(defvoo nnultimate-groups nil)
57(defvoo nnultimate-headers nil)
58(defvoo nnultimate-articles nil)
59
60;;; Interface functions
61
62(nnoo-define-basics nnultimate)
63
64(deffoo nnultimate-retrieve-headers (articles &optional group server fetch-old)
65 (nnultimate-possibly-change-server group server)
66 (unless gnus-nov-is-evil
67 (let* ((last (car (last articles)))
68 (did nil)
69 (start 1)
70 (entry (assoc group nnultimate-groups))
71 (sid (nth 2 entry))
72 (topics (nth 4 entry))
73 (mapping (nth 5 entry))
74 (old-total (or (nth 6 entry) 1))
75 (furl "forumdisplay.cgi?action=topics&number=%d&DaysPrune=1000")
76 (furls (list (concat nnultimate-address (format furl sid))))
77 headers article subject score from date lines parent point
78 contents tinfo fetchers map elem a href garticles topic old-max
79 inc datel table string current-page total-contents pages
80 farticles forum-contents parse furl-fetched mmap farticle)
81 (setq map mapping)
82 (while (and (setq article (car articles))
83 map)
84 (while (and map
85 (or (> article (caar map))
86 (< (cadar map) (caar map))))
87 (pop map))
88 (when (setq mmap (car map))
89 (setq farticle -1)
90 (while (and article
91 (<= article (nth 1 mmap)))
92 ;; Do we already have a fetcher for this topic?
93 (if (setq elem (assq (nth 2 mmap) fetchers))
94 ;; Yes, so we just add the spec to the end.
95 (nconc elem (list (cons article
96 (+ (nth 3 mmap) (incf farticle)))))
97 ;; No, so we add a new one.
98 (push (list (nth 2 mmap)
99 (cons article
100 (+ (nth 3 mmap) (incf farticle))))
101 fetchers))
102 (pop articles)
103 (setq article (car articles)))))
104 ;; Now we have the mapping from/to Gnus/nnultimate article numbers,
105 ;; so we start fetching the topics that we need to satisfy the
106 ;; request.
107 (if (not fetchers)
108 (save-excursion
109 (set-buffer nntp-server-buffer)
110 (erase-buffer))
111 (setq nnultimate-articles nil)
112 (mm-with-unibyte-buffer
113 (dolist (elem fetchers)
114 (setq pages 1
115 current-page 1
116 total-contents nil)
117 (while (<= current-page pages)
118 (erase-buffer)
119 (setq subject (nth 2 (assq (car elem) topics)))
120 (setq href (nth 3 (assq (car elem) topics)))
121 (if (= current-page 1)
122 (nnweb-insert href)
123 (string-match "\\.html$" href)
124 (nnweb-insert (concat (substring href 0 (match-beginning 0))
125 "-" (number-to-string current-page)
126 (match-string 0 href))))
127 (goto-char (point-min))
128 (setq contents
129 (ignore-errors (w3-parse-buffer (current-buffer))))
130 (setq table (nnultimate-find-forum-table contents))
131 (setq string (mapconcat 'identity (nnweb-text table) ""))
132 (when (string-match "topic is \\([0-9]\\) pages" string)
133 (setq pages (string-to-number (match-string 1 string)))
134 (setcdr table nil)
135 (setq table (nnultimate-find-forum-table contents)))
136 (setq contents (cdr (nth 2 (car (nth 2 table)))))
137 (setq total-contents (nconc total-contents contents))
138 (incf current-page))
139 ;;(setq total-contents (nreverse total-contents))
140 (dolist (art (cdr elem))
141 (if (not (nth (1- (cdr art)) total-contents))
142 () ;(debug)
143 (push (list (car art)
144 (nth (1- (cdr art)) total-contents)
145 subject)
146 nnultimate-articles)))))
147 (setq nnultimate-articles
148 (sort nnultimate-articles 'car-less-than-car))
149 ;; Now we have all the articles, conveniently in an alist
150 ;; where the key is the Gnus article number.
151 (dolist (articlef nnultimate-articles)
152 (setq article (nth 0 articlef)
153 contents (nth 1 articlef)
154 subject (nth 2 articlef))
155 (setq from (mapconcat 'identity
156 (nnweb-text (car (nth 2 contents)))
157 " ")
158 datel (nnweb-text (nth 2 (car (cdr (nth 2 contents))))))
159 (while datel
160 (when (string-match "Posted" (car datel))
161 (setq date (substring (car datel) (match-end 0))
162 datel nil))
163 (pop datel))
164