aboutsummaryrefslogtreecommitdiff
path: root/main.rkt
diff options
context:
space:
mode:
Diffstat (limited to 'main.rkt')
-rw-r--r--main.rkt43
1 files changed, 43 insertions, 0 deletions
diff --git a/main.rkt b/main.rkt
new file mode 100644
index 0000000..65e9f49
--- /dev/null
+++ b/main.rkt
@@ -0,0 +1,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)))))