blob: 65e9f493cb7ca680f8e4e23a935d6a8d480515b9 (
about) (
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
|
#lang typed/racket
(require typed/xml)
(require typed/net/url)
(require srfi/2)
(require/typed/provide html
[read-html-as-xml (-> Input-Port (Listof XML-Content))])
(: get-youtube-rss-url (-> String (Option String)))
(define (get-youtube-rss-url url)
(define-values (status-line _header in)
(http-sendrecv/url (string->url url)))
(cond
[(and-let* ([code (status-line->code status-line)]
[(= code 200)])
(find-channel-id (map xml->xexpr (read-html-as-xml in))))
=> (lambda (channel-id)
(string-append "https://www.youtube.com/feeds/videos.xml?channel_id=" channel-id))]
[else #f]))
(: find-channel-id (-> Any (Option String)))
(define (find-channel-id xexpr)
(match xexpr
[`(meta ((content ,content) (itemprop "identifier")))
(and (string? content)
content)]
[(list* h t)
(or (find-channel-id h) (find-channel-id t))]
[else #f]))
(: status-line->code (-> Bytes (Option Number)))
(define (status-line->code status-line)
(string->number (second (string-split (bytes->string/utf-8 status-line)))))
(module+ main
(require racket/cmdline)
(command-line
#:program "get-youtube-rss-url"
#:once-each
#:args (url)
(and (string? url)
(displayln (get-youtube-rss-url url)))))
|