eww.scm (4122B)
1 (define-module (home jaynw eww) 2 #:use-module (guix gexp) 3 #:export (eww-saint-cards)) 4 5 ;; This is a guile script that generates "prayer cards" that correspond to the saints 6 ;; of the day. This is done by scraping the OCA website and producing valid yuck 7 ;; syntax to be used with a `literal` widget in eww. 8 9 ;; TODO: Batch process icons 10 ;; TODO: Write better sxml code 11 12 (define eww-saint-cards 13 (program-file "eww-saint-cards" 14 #~(begin 15 (use-modules (ice-9 textual-ports) 16 (ice-9 popen) 17 (ice-9 rdelim) 18 (srfi srfi-9) 19 (sxml xpath) 20 (htmlprag)) 21 22 ;; Used to help make collection clearer 23 (define-record-type saint 24 (make-saint name image-url) 25 saint? 26 (name saint-name) 27 (image-url saint-image-url)) 28 29 ;; Download content from a url and return the file path to it 30 (define (curl-tmp-file url) 31 (let* ((output (open-pipe* OPEN_READ "mktemp")) 32 (file (read-line output 'trim))) 33 (close-port output) 34 (system* "curl" "-s" url "-o" file) 35 file)) 36 37 ;; Return the saint name from an article 38 (define (extract-name article) 39 (car 40 ((node-join 41 (select-kids (node-typeof? 'h2)) 42 (select-kids (node-typeof? '*text*))) 43 article))) 44 45 ;; Return the icon url for an article or #f if there is none 46 (define (extract-image-url article) 47 (let ((url ((node-join 48 (node-closure (node-typeof? 'img)) 49 (select-kids (node-typeof? '@)) 50 (select-kids (node-typeof? 'src)) 51 (select-kids (node-typeof? '*text*))) 52 article))) 53 (if (null? url) 54 #f 55 (car url)))) 56 57 ;; Extract articles and a saint record from each 58 (define (extract-saints sxml) 59 (map-union 60 (lambda (article) 61 (make-saint (string-trim-right (extract-name article)) 62 (extract-image-url article))) 63 ((node-closure (node-typeof? 'article)) sxml))) 64 65 ;; Fetch html, translate it to sxml and iterate over the extracted 66 ;; articles, producing yuck syntax 67 (display "(box ") 68 (let* ((output (open-pipe* 69 OPEN_READ 70 "curl" "-s" 71 "https://www.oca.org/saints/lives")) 72 (file (get-string-all output)) 73 (sxml-file (html->sxml file #:strict? #t))) 74 (close-port output) 75 (for-each 76 (lambda (saint) 77 (display "(box :class \"card\" ") 78 (let ((url (saint-image-url saint))) 79 (if url 80 (format #t "(image :tooltip \"~a\" :path \"~a\") " 81 (saint-name saint) 82 (curl-tmp-file url)) 83 (format #t "(label :justify \"center\" :wrap true :text \"~a\")" 84 (saint-name saint)))) 85 (display ") ")) 86 (extract-saints sxml-file))) 87 (display ")"))))