blob: a9518c8d26378917cb72c243a8db6b466012cb1e (
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
|
#!/usr/bin/guile \
-e main -s
!#
;;; Commentary:
;; Bulids an index of "all" locations at LiU, and prints it as a JSON
;; object on the form { "location name": "url-fragment", ... }. These
;; fragments should be appended to the base "https://old.liu.se/karta/".
;;
;; See static/user/user-additions.js for this script in action.
;;; Code:
(use-modules (srfi srfi-1)
(srfi srfi-88)
(web client)
(web response)
(ice-9 rdelim)
(ice-9 format)
(ice-9 getopt-long)
(sxml gumbo)
(sxml match)
((sxml xpath) :select (sxpath))
((hnh util) :select (-> ->>))
(json))
;; Parse string as HTML, find all links which are "map links",
;; and return them as an association list from name to url-fragments.
(define (extract-data string)
(define rx (make-regexp "^karta\\?"))
;; for (let el of document.querySelectorAll('a[href*="karta?"]')) {
;; ret[el.textContent.trim().toUpperCase()] = el.href
;; }
(->> (html->sxml string)
((sxpath '(// a)))
(map (lambda (node)
(sxml-match node
[(a (@ (href ,href)) ,b0 ,body ...)
(cons href b0)])))
(filter (lambda (pair) (regexp-exec rx (car pair))))
(map (lambda (pair) (cons (string-upcase (string-trim-both (cdr pair)))
(car pair))))))
;; Open a HTTP request to the given URL, and return the
;; response body as a port.
(define (open-input-url url)
(define-values (response body) (http-get url streaming?: #t))
(unless (= 200 (response-code response))
(format #t "Fetching index failed with ~a ~a~%"
(response-code response)
(response-reason-phrase response))
(throw 'misc-error "get-from-url" "~{~s~%~}" (response-headers response))
(exit 1))
body)
(define (display-help)
(format #t "Usage: fetch-liu-map-index.scm [--url=url] [--file=file]~%")
(newline)
(for-each (lambda (line) (display line) (newline))
((@ (text flow) flow-text)
"(Possibly) fetches, and parses Linköpings Universities list of locations. The return is a simple JSON-object where the keys are the location names, and the values are URL fragments. The --file flag exists since the TLS bindings in Guile are currently broken, and is mainly useful for taking input from a cURL pipe."))
(newline))
(define option-spec
'((url (value #t))
(file (value #t))
(help (single-char #\h))))
(define (main args)
(define options (getopt-long args option-spec))
(when (option-ref options 'help #f)
(display-help)
(exit 0))
(let ((port
(cond ((option-ref options 'url #f) => open-input-url)
((string=? "-" (option-ref options 'file ""))
(current-input-port))
((option-ref options 'file #f) => open-input-file)
(else (open-input-url "https://old.liu.se/karta/list?l=sv")))))
(-> port read-string extract-data scm->json)
(newline)))
|