summaryrefslogtreecommitdiff
path: root/haunt/jakob/utils/webmention.scm
blob: 9f1d289b8194efa3e4d7c080a37eaf4456cf063d (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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
;;; Copyright © 2019 - 2022 Jakob L. Kreuze <zerodaysfordays@sdf.org>
;;;
;;; This program is free software; you can redistribute it and/or
;;; modify it under the terms of the GNU General Public License as
;;; published by the Free Software Foundation; either version 3 of the
;;; License, or (at your option) any later version.
;;;
;;; This program is distributed in the hope that it will be useful,
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;;; General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with this program. If not, see
;;; <http://www.gnu.org/licenses/>.

(define-module (jakob utils webmention)
  #:use-module (ice-9 receive)
  #:use-module (ice-9 iconv)
  #:use-module (ice-9 match)
  #:use-module (srfi srfi-19)
  #:use-module (srfi srfi-43)
  #:use-module (json)
  #:use-module (web client)
  #:use-module (web response)
  #:use-module (oop goops)
  #:export (render-comment-view
            fetch-webmentions))

(define (strip uri)
  (let* ((needle "://")
         (index (string-contains uri needle)))
    (if index
        (strip (substring uri (+ index (string-length needle))))
        uri)))

(define (format-comment object)
  (let* ((author (assoc-ref object "author"))
         (author-name (assoc-ref author "name"))
         (author-photo (assoc-ref author "photo"))
         (author-url (assoc-ref author "url"))
         (content (assoc-ref object "content"))
         (content-text (assoc-ref content "text"))
         (published-time (assoc-ref object "published"))
         (received-time (assoc-ref object "wm-received"))
         (url (assoc-ref object "url")))
    `(li (@ (class "p-comment h-cite comment comment-source-webmention"))
         (img (@ (class "comment-source-identifier")
                 (alt "Webmention logo")
                 (src "/static/image/webmention-logo.png")))
         (div (@ (class "p-author h-card author"))
              (img (@ (class "u-photo")
                      (src ,(if (string-prefix? author-url "https://lobste.rs/")
                                "/static/image/lobsters.png"
                                (or author-photo "/static/image/default-icon.png")))))
              (a (@ (class "p-name u-url")
                    (href ,author-url))
                 ,author-name)
              (a (@ (class "author-url")
                    (href ,author-url))
                 ,(strip author-url)))
         (div (@ (class "e-content p-name comment-content"))
              ,content-text)
         (div (@ (class "metaline"))
              (a (@ (class "u-url")
                    (href ,url))
                 (time (@ (class "dt-published")
                          (datetime ,(or published-time received-time)))
                       ,(date->string
                         (string->date (if (eqv? 'null published-time)
                                           (if (eqv? 'null received-time)
                                               (current-time)
                                               received-time)
                                           published-time)
                                       "~Y~m~d~H~M~S")
                         "~B ~e, ~Y at ~H:~M")))))))

(define (format-interaction object)
  (let* ((author (assoc-ref object "author"))
         (author-name (assoc-ref author "name"))
         (author-photo (assoc-ref author "photo"))
         (author-url (assoc-ref author "url")))
    `(li (@ (class "p-comment h-cite interaction comment-source-webmention"))
         (a (@ (href ,author-url))
            (img (@ (class "u-photo")
                    (src ,(if (string-prefix? author-url "https://lobste.rs/")
                              "/static/image/lobsters.png"
                              (or author-photo "/static/image/default-icon.png"))))))
         (div (@ (class "e-content p-name comment-content"))
              (em
               ,(match (assoc-ref object "wm-property")
                  ("repost-of" "Reposted this!")
                  ("like-of" "Favorited this!")
                  (_ "[No Text Provided!]"))))
         (img (@ (class "comment-source-identifier")
                 (alt "Webmention logo")
                 (src "/static/image/webmention-logo.png"))))))

(define (render-comment-view response)
  (vector->list
   (vector-map (lambda (_ x)
                 (if (and (assoc-ref x "wm-property")
                          (or (string= (assoc-ref x "wm-property") "in-reply-to")
                              (string= (assoc-ref x "wm-property") "mention-of")))
                     (format-comment x)
                     (format-interaction x)))
               (assoc-ref response "children"))))

(define (fetch-webmentions slug)
  (define prefixes '("http://jakob.space/" "https://jakob.space/"
                     "http://jakob.space/blog/" "https://jakob.space/blog/"))
  (let ((url (format #f "https://webmention.io/api/mentions.jf2?per-page=200&page=0&~a"
                     (string-join
                      (map (lambda (pre)
                             (format #f "target[]=~a~a.html" pre slug))
                           prefixes)
                      "&"))))
    (receive (response-status response-body)
        (http-request url)
      (call-with-input-string (bytevector->string response-body "UTF-8") json->scm))))