summaryrefslogtreecommitdiff
path: root/src/weepinbell/webserver/feed.clj
blob: 7a78a9af908f4aee26ba9289ba35db4031fa61d1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
(ns weepinbell.webserver.feed
  "Service generating RSS feed for each domain."
  (:require [clj-rss.core :as rss]
            [weepinbell.utils.url :refer [get-domain]]
            [weepinbell.utils.digest :refer [digest]])
  (:import [java.time Instant]))

(defn- make-feed-items [wms config]
  (->> wms
       (map #(let [wm (:webmention %)
                   id (if-let [id (:id wm)] id
                              (digest (str (:source wm) (:target wm))))
                   permalink (str (:base-url config) "/api/mention/" id)
                   modified (:modified wm)
                   pub-date (when modified
                              (Instant/ofEpochMilli modified))]
               {:title (str (-> wm :source get-domain) " -> " (:target wm))
                :link (:source wm)
                :guid permalink
                :pubDate pub-date}))
       (take-last (:feed-length config))
       doall))

(defn- make-feed-channel [title desc link wms config]
  (let [metadata {:title title
                  :link link
                  :description desc}
        gen (partial rss/channel-xml metadata)]
    (if-let [items (make-feed-items wms config)]
      (gen items)
      (gen))))

(defn rss
  "Generate RSS XML response, or 404 JSON response when not found."
  [domain storage config]
  (if ((set (:allowed-target-domains config)) domain)
    (let [wms ((:get-by-domain storage) domain)]
      {:headers {"Content-Type" "application/xml"}
       :body (make-feed-channel
              (str "Webmentions Feed of " domain)
              (str "Webmentions sent to " domain ", provided by Weepinbell.")
              (:base-url config)
              wms config)})
    {:status 404
     :headers {"Content-Type" "application/json"}
     :body {:message "No feed for this domain."}}))