git.fiddlerwoaroof.com
Raw Blame History
(declaim (optimize (speed 0) (safety 3) (debug 3)))
(in-package :alimenta.pull-feed)

(defun fetch-doc-from-url (url)
  (let ((plump:*tag-dispatchers* plump:*xml-tags*)
        (drakma:*text-content-types* (concatenate 'list
                                                  '(("application" . "atom+xml") ("application" . "rss+xml"))
                                                  drakma:*text-content-types*)))
    (plump:parse (drakma:http-request url))))

(define-condition fetch-error () ())
(define-condition feed-ambiguous (fetch-error) ((choices :initarg :choices :initform nil)))
(define-condition no-feed (fetch-error) ((url :initarg :url :initform nil)))

(defun feed-ambiguous (choices)
  (error 'feed-ambiguous
         :choices choices))

(defun no-feed (url)
  (cerror "Skip this feed" 'no-feed :url url))

(defun fetch-feed-from-url (url &key type)
  (let* ((feeds (alimenta.discover:discover-feed (drakma:http-request url)))
         (feeds (if type (remove-if-not (lambda (x) (eql type (car x))) feeds) feeds)))
    (format t "~a << type" type)
    (if (not feeds) (no-feed url)
      (fetch-doc-from-url
        (cdar 
          (restart-case
            (if (cdr feeds) (feed-ambiguous feeds) feeds)
            (take-first-feed nil
                             :report (lambda (s) (format s "Take the first feed"))
                             feeds)
            (take-nth-feed (n)
                           :report (lambda (s) (format s "Take the nth feed"))
                           (list (elt feeds n)))
            (select-feed (selector)
                         :report (lambda (s) (format s "Provide a function to select the right feed"))
                         (find-if selector feeds))))))))