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