Add arch taglines
[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)
95fa1ff7
SZ
59(defvar nnultimate-table-regexp
60 "postings.*editpost\\|forumdisplay\\|Forum[0-9]+/HTML\\|getbio")
c113de23
GM
61
62;;; Interface functions
63
64(nnoo-define-basics nnultimate)
65
66(deffoo nnultimate-retrieve-headers (articles &optional group server fetch-old)
67 (nnultimate-possibly-change-server group server)
68 (unless gnus-nov-is-evil
69 (let* ((last (car (last articles)))
70 (did nil)
71 (start 1)
72 (entry (assoc group nnultimate-groups))
73 (sid (nth 2 entry))
74 (topics (nth 4 entry))
75 (mapping (nth 5 entry))
76 (old-total (or (nth 6 entry) 1))
77 (furl "forumdisplay.cgi?action=topics&number=%d&DaysPrune=1000")
78 (furls (list (concat nnultimate-address (format furl sid))))
95fa1ff7
SZ
79 (nnultimate-table-regexp
80 "postings.*editpost\\|forumdisplay\\|getbio")
c113de23
GM
81 headers article subject score from date lines parent point
82 contents tinfo fetchers map elem a href garticles topic old-max
95fa1ff7 83 inc datel table current-page total-contents pages
c113de23
GM
84 farticles forum-contents parse furl-fetched mmap farticle)
85 (setq map mapping)
86 (while (and (setq article (car articles))
87 map)
95fa1ff7
SZ
88 ;; Skip past the articles in the map until we reach the
89 ;; article we're looking for.
c113de23
GM
90 (while (and map
91 (or (> article (caar map))
92 (< (cadar map) (caar map))))
93 (pop map))
94 (when (setq mmap (car map))
95 (setq farticle -1)
96 (while (and article
97 (<= article (nth 1 mmap)))
98 ;; Do we already have a fetcher for this topic?
99 (if (setq elem (assq (nth 2 mmap) fetchers))
100 ;; Yes, so we just add the spec to the end.
101 (nconc elem (list (cons article
102 (+ (nth 3 mmap) (incf farticle)))))
103 ;; No, so we add a new one.
104 (push (list (nth 2 mmap)
105 (cons article
106 (+ (nth 3 mmap) (incf farticle))))
107 fetchers))
108 (pop articles)
109 (setq article (car articles)))))
95fa1ff7 110 ;; Now we have the mapping from/to Gnus/nnultimate article numbers,
c113de23
GM
111 ;; so we start fetching the topics that we need to satisfy the
112 ;; request.
113 (if (not fetchers)
114 (save-excursion
115 (set-buffer nntp-server-buffer)
116 (erase-buffer))
117 (setq nnultimate-articles nil)
118 (mm-with-unibyte-buffer
119 (dolist (elem fetchers)
120 (setq pages 1
121 current-page 1
122 total-contents nil)
123 (while (<= current-page pages)
124 (erase-buffer)
125 (setq subject (nth 2 (assq (car elem) topics)))
126 (setq href (nth 3 (assq (car elem) topics)))
127 (if (= current-page 1)
128 (nnweb-insert href)
129 (string-match "\\.html$" href)
130 (nnweb-insert (concat (substring href 0 (match-beginning 0))
131 "-" (number-to-string current-page)
132 (match-string 0 href))))
133 (goto-char (point-min))
134 (setq contents
135 (ignore-errors (w3-parse-buffer (current-buffer))))
136 (setq table (nnultimate-find-forum-table contents))
95fa1ff7
SZ
137 (goto-char (point-min))
138 (when (re-search-forward "topic is \\([0-9]+\\) pages" nil t)
139 (setq pages (string-to-number (match-string 1))))
c113de23
GM
140 (setq contents (cdr (nth 2 (car (nth 2 table)))))
141 (setq total-contents (nconc total-contents contents))
142 (incf current-page))
95fa1ff7
SZ
143 (when t
144 (let ((i 0))
145 (dolist (co total-contents)
146 (push (list (or (nnultimate-topic-article-to-article
147 group (car elem) (incf i))
148 1)
149 co subject)
150 nnultimate-articles))))
151 (when nil
152 (dolist (art (cdr elem))
153 (when (nth (1- (cdr art)) total-contents)
154 (push (list (car art)
155 (nth (1- (cdr art)) total-contents)
156 subject)
157 nnultimate-articles))))))
c113de23
GM
158 (setq nnultimate-articles
159 (sort nnultimate-articles 'car-less-than-car))
160 ;; Now we have all the articles, conveniently in an alist
161 ;; where the key is the Gnus article number.
162 (dolist (articlef nnultimate-articles)
163 (setq article (nth 0 articlef)
164 contents (nth 1 articlef)
165 subject (nth 2 articlef))
166 (setq from (mapconcat 'identity
167 (nnweb-text (car (nth 2 contents)))
168 " ")
169 datel (nnweb-text (nth 2 (car (cdr (nth 2 contents))))))
170 (while datel
171 (when (string-match "Posted" (car datel))
172 (setq date (substring (car datel) (match-end 0))
173 datel nil))
174 (pop datel))
95fa1ff7
SZ
175 (when date
176 (setq date (delete "" (split-string
177