(gnus-summary-limit-to-singletons): Fix typo.
[gnus] / lisp / nnslashdot.el
index 551d3de..591e92b 100644 (file)
@@ -1,5 +1,7 @@
 ;;; nnslashdot.el --- interfacing with Slashdot
-;; Copyright (C) 1999 Free Software Foundation, Inc.
+
+;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004,
+;;   2005, 2006 Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;; Keywords: news
 
 ;; 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.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
 
 ;;; Commentary:
 
-;; Note: You need to have `url' and `w3' installed for this
-;; backend to work.
-
 ;;; Code:
 
 (eval-when-compile (require 'cl))
 (require 'gnus)
 (require 'nnmail)
 (require 'mm-util)
-(require 'nnweb)
-(eval-when-compile
-  (ignore-errors
-    (require 'w3)
-    (require 'url)
-    (require 'w3-forms)))
-;; Report failure to find w3 at load time if appropriate.
-(eval '(progn
-        (require 'w3)
-        (require 'url)
-        (require 'w3-forms)))
+(require 'mm-url)
 
 (nnoo-declare nnslashdot)
 
     "http://slashdot.org/article.pl?sid=%s&mode=nocomment"
   "Where nnslashdot will fetch the article from.")
 
+(defvoo nnslashdot-backslash-url "http://slashdot.org/slashdot.xml"
+  "Where nnslashdot will fetch the stories from.")
+
+(defvoo nnslashdot-use-front-page nil
+  "Use the front page in addition to the backslash page.")
+
 (defvoo nnslashdot-threshold -1
   "The article threshold.")
 
 (defvoo nnslashdot-group-number 0
   "The number of non-fresh groups to keep updated.")
 
+(defvoo nnslashdot-login-name ""
+  "The login name to use when posting.")
+
+(defvoo nnslashdot-password ""
+  "The password to use when posting.")
+
 ;;; Internal variables
 
 (defvar nnslashdot-groups nil)
 
 (deffoo nnslashdot-retrieve-headers (articles &optional group server fetch-old)
   (nnslashdot-possibly-change-server group server)
-  (unless gnus-nov-is-evil
-    (if nnslashdot-threaded
-       (nnslashdot-threaded-retrieve-headers articles group)
-      (nnslashdot-sane-retrieve-headers articles group))))
-  
-(deffoo nnslashdot-threaded-retrieve-headers (articles group)
-  (let ((last (car (last articles)))
-       (did nil)
-       (start 1)
-       (sid (caddr (assoc group nnslashdot-groups)))
-       (first-comments t)
-       (startats '(1))
-       headers article subject score from date lines parent point s)
+  (condition-case why
+      (unless gnus-nov-is-evil
+       (nnslashdot-retrieve-headers-1 articles group))
+    (search-failed (nnslashdot-lose why))))
+
+(deffoo nnslashdot-retrieve-headers-1 (articles group)
+  (let* ((last (car (last articles)))
+        (start (if nnslashdot-threaded 1 (pop articles)))
+        (entry (assoc group nnslashdot-groups))
+        (sid (nth 2 entry))
+        (first-comments t)
+        headers article subject score from date lines parent point cid
+        s startats changed)
     (save-excursion
       (set-buffer nnslashdot-buffer)
       (let ((case-fold-search t))
        (erase-buffer)
        (when (= start 1)
-         (nnweb-insert (format nnslashdot-article-url sid))
+         (mm-url-insert (format nnslashdot-article-url sid) t)
          (goto-char (point-min))
-         (search-forward "Posted by ")
-         (when (looking-at "<a[^>]+>\\([^<]+\\)")
-           (setq from (match-string 1)))
-         (search-forward " on ")
+         (if (eobp)
+             (error "Couldn't open connection to slashdot"))
+         (re-search-forward "Posted by[ \t\r\n]+")
+         (when (looking-at "\\(<a[^>]+>\\)?[ \t\r\n]*\\([^<\r\n]+\\)")
+           (setq from (mm-url-decode-entities-string (match-string 2))))
+         (search-forward "on ")
          (setq date (nnslashdot-date-to-date
                      (buffer-substring (point) (1- (search-forward "<")))))
-         (forward-line 2)
-         (setq lines (count-lines
-                      (point)
-                      (search-forward
-                       "A href=http://slashdot.org/article.pl")))
+         (setq lines (/ (- (point)
+                           (progn (forward-line 1) (point)))
+                        60))
          (push
           (cons
            1
            (make-full-mail-header
-            1 group from date (concat "<" sid "%1@slashdot>")
+            1 group from date
+            (concat "<" sid "%1@slashdot>")
             "" 0 lines nil nil))
-          headers))
-       (while (and (setq start (pop startats))
-                   (< start last))
+          headers)
+         (setq start (if nnslashdot-threaded 2 (pop articles))))
+       (while (and start (<= start last))
          (setq point (goto-char (point-max)))
-         (nnweb-insert
-          (format nnslashdot-comments-url sid nnslashdot-threshold 0 start))
-         (when first-comments
+         (mm-url-insert
+          (format nnslashdot-comments-url sid
+                  nnslashdot-threshold 0 (- start 2))
+          t)
+         (when (and nnslashdot-threaded first-comments)
            (setq first-comments nil)
            (goto-char (point-max))
            (while (re-search-backward "startat=\\([0-9]+\\)" nil t)
              (unless (memq s startats)
                (push s startats)))
            (setq startats (sort startats '<)))
+         (setq article (if (and article (< start article)) article start))
          (goto-char point)
          (while (re-search-forward
-                 "<a name=\"\\([0-9]+\\)\"><b>\\([^<]+\\)</b>.*score:\\([^)]+\\))"
+                 "<a name=\"\\([0-9]+\\)\">\\([^<]+\\)\\(?:.*\n\\)\\{2,10\\}.*score:\\([^)]+\\))"
                  nil t)
-           (setq article (string-to-number (match-string 1))
+           (setq cid (match-string 1)
                  subject (match-string 2)
                  score (match-string 3))
+           (unless (assq article (nth 4 entry))
+             (setcar (nthcdr 4 entry) (cons (cons article cid) (nth 4 entry)))
+             (setq changed t))
            (when (string-match "^Re: *" subject)
              (setq subject (concat "Re: " (substring subject (match-end 0)))))
-           (forward-line 1)
-           (if (looking-at
-                "by <a[^>]+>\\([^<]+\\)</a>[ \t\n]*.*(\\([^)]+\\))")
-               (setq from (concat (match-string 1)
-                                  " <" (match-string 2) ">"))
-             (looking-at "by \\(.+\\) on ")
-             (setq from (match-string 1)))
-           (goto-char (- (match-end 0) 5))
-           (search-forward " on ")
+           (setq subject (mm-url-decode-entities-string subject)
+                 from "")
+           (when (re-search-forward "by[ \t\n]+<[^>]+>\\([^<(]+\\)" nil t)
+             (setq from
+                   (concat
+                    (mm-url-decode-entities-string (match-string 1))
+                    " <nobody@slashdot.org>")))
+           (search-forward "on ")
            (setq date
                  (nnslashdot-date-to-date
-                  (buffer-substring (point) (progn (end-of-line) (point)))))
-           (setq lines (/ (abs (- (search-forward "<td ")
-                                  (search-forward "</td>")))
+                  (buffer-substring
+                   (point) (progn (skip-chars-forward "^()<>\n\r") (point)))))
+           (setq lines (/ (abs (- (search-forward "<div")
+                                  (search-forward "</div>")))
                           70))
-           (forward-line 2)
-           (setq parent
-                 (if (looking-at ".*cid=\\([0-9]+\\)")
-                     (match-string 1)
-                   nil))
-           (setq did t)
+           (if (not
+                (re-search-forward ".*cid=\\([0-9]+\\)\">Parent</A>" nil t))
+               (setq parent nil)
+             (setq parent (match-string 1))
+             (when (string= parent "0")
+               (setq parent nil)))
            (push
             (cons
-             (1+ article)
+             article
              (make-full-mail-header
-              (1+ article)
+              article
               (concat subject " (" score ")")
               from date
-              (concat "<" sid "%"
-                      (number-to-string (1+ article)) 
-                      "@slashdot>")
+              (concat "<" sid "%" cid "@slashdot>")
               (if parent
-                  (concat "<" sid "%"
-                          (number-to-string (1+ (string-to-number parent)))
-                          "@slashdot>")
+                  (concat "<" sid "%" parent "@slashdot>")
                 "")
               0 lines nil nil))
-            headers)))))
+            headers)
+           (while (and articles (<= (car articles) article))
+             (pop articles))
+           (setq article (1+ article)))
+         (if nnslashdot-threaded
+             (progn
+               (setq start (pop startats))
+               (if start (setq start (+ start 2))))
+           (setq start (pop articles))))))
+    (if changed (nnslashdot-write-groups))
     (setq nnslashdot-headers (sort headers 'car-less-than-car))
     (save-excursion
       (set-buffer nntp-server-buffer)
       (erase-buffer)
-      (dolist (header nnslashdot-headers)
-       (nnheader-insert-nov (cdr header))))
-    'nov))
-
-(deffoo nnslashdot-sane-retrieve-headers (articles group)
-  (let ((last (car (last articles)))
-       (did nil)
-       (start (max (1- (car articles)) 1))
-       (sid (caddr (assoc group nnslashdot-groups)))
-       headers article subject score from date lines parent point)
-    (save-excursion
-      (set-buffer nnslashdot-buffer)
-      (erase-buffer)
-      (when (= start 1)
-       (nnweb-insert (format nnslashdot-article-url sid))
-       (goto-char (point-min))
-       (search-forward "Posted by ")
-       (when (looking-at "<a[^>]+>\\([^<]+\\)")
-         (setq from (match-string 1)))
-       (search-forward " on ")
-       (setq date (nnslashdot-date-to-date
-                   (buffer-substring (point) (1- (search-forward "<")))))
-       (forward-line 2)
-       (setq lines (count-lines (point)
-                                (search-forward
-                                 "A href=http://slashdot.org/article.pl")))
-       (push
-        (cons
-         1
-         (make-full-mail-header
-          1 group from date (concat "<" sid "%1@slashdot>")
-          "" 0 lines nil nil))
-        headers))
-      (while (or (not article)
-                (and did
-                     (< article last)))
-       (when article
-         (setq start (1+ article)))
-       (setq point (goto-char (point-max)))
-       (nnweb-insert
-        (format nnslashdot-comments-url sid nnslashdot-threshold 4 start))
-       (goto-char point)
-       (while (re-search-forward
-               "<a name=\"\\([0-9]+\\)\"><b>\\([^<]+\\)</b>.*score\\([^)]+\\))"
-               nil t)
-         (setq article (string-to-number (match-string 1))
-               subject (match-string 2)
-               score (match-string 3))
-         (forward-line 1)
-         (if (looking-at
-              "by <a[^>]+>\\([^<]+\\)</a>[ \t\n]*.*(\\([^)]+\\))")
-             (setq from (concat (match-string 1) " <" (match-string 2) ">"))
-           (looking-at "by \\(.+\\) on ")
-           (setq from (match-string 1)))
-         (goto-char (- (match-end 0) 5))
-         (search-forward " on ")
-         (setq date
-               (nnslashdot-date-to-date
-                (buffer-substring (point) (progn (end-of-line) (point)))))
-         (setq lines (/ (abs (- (search-forward "<td ")
-                                (search-forward "</td>")))
-                        70))
-         (forward-line 2)
-         (setq parent
-               (if (looking-at ".*cid=\\([0-9]+\\)")
-                   (match-string 1)
-                 nil))
-         (setq did t)
-         (push
-          (cons
-           (1+ article)
-           (make-full-mail-header
-            (1+ article) (concat subject " (" score ")")
-            from date
-            (concat "<" sid "%"
-                    (number-to-string (1+ article)) 
-                    "@slashdot>")
-            (if parent
-                (concat "<" sid "%"
-                        (number-to-string (1+ (string-to-number parent)))
-                        "@slashdot>")
-          &nbs